Object-Oriented Programming

“객체 지향”이라는 말은 IT에 몸담고 있는 사람 모두에게 친숙한 단어입니다. 설계를 하거나 프로그래밍을 할 때, “객체 지향”으로 하라는 뜻은 무엇일까요? 그리고 클래스와 객체가 무엇이고 왜 쓰는 걸까요?

이 글은 이제 막 프로그래밍에 입문한 사람들을 대상으로 쓰였습니다. 객체 지향에 대한 자세한 설명은 없으니, 심심한 분들만 읽어보세요.

객체 지향(Object-Oriented), 왜 쓰는걸까

Python, Java, C++ 등.. 대부분의 프로그래밍 언어 문법 관련 책들을 보면 변수, 제어문 등을 배운 뒤에 클래스와 객체 등에 대해 배웁니다. 프로그래밍을 처음 시작하는 많은 분들이 제어문까지야 자연스럽게 받아들이는데, 클래스를 배우기 시작하면서 이걸 왜 써야 하나 궁금해하는 분들이 많습니다. 제어문이나 함수(메서드)만으로도 프로그래밍 할 수 있을 것 같은데, 클래스는 왜 쓰는 걸까요?

여러분이 클래스의 필요성을 느끼지 못하는 이유는 간단합니다. 이제 막 프로그래밍을 시작했고, 따라서 작성하는 프로그램이 굉장히 단순하기 때문입니다. 간단한 코드를 작성할 때는 객체 지향을 활용할 이유가 별로 없습니다. 실제로 과거에는 클래스 없이 프로그래밍을 했었습니다. 프로그래밍 언어의 역사를 보면, 현대의 프로그래밍 언어는 1950년대부터 만들어지기 시작했고, 객체 지향의 붐은 1980~1990년 대 사이에 일어났으며, 자바는 1995년에 만들어졌습니다. 이 말은, 과거에는 클래스를 활용하지 않고도 프로그래밍을 잘해왔다 라는 뜻입니다.

그런데 프로그램이 복잡해진다면 이야기가 달라집니다. 여러분이 10만 줄 이상의 코드를 클래스 없이 작성하다 보면, 뭔가 다른 방법의 필요성을 깨달을 거라 확신합니다. 엄청나게 긴 코드를 객체 지향이 아닌 다른 방식으로 작성하는 것은 매우 힘들 가능성이 높습니다.

우리가 사용하는 프로그램의 복잡성은 컴퓨터가 발명된 이래 계속해서 증가했습니다. 컴퓨터의 성능이 점점 좋아지다 보니, 동작시킬 수 있는 프로그램의 크기도 점점 커지게 되고, 따라서 소프트웨어 역시 복잡해지게 되는 것이죠. 예를 들어, Windows 95의 소스 코드는 1500만 줄 정도이며, Windows XP의 소스코드는 4000만 줄 정도입니다. 인간의 지능에는 한계가 있습니다. 같은 방법으로 더더 복잡한 프로그램을 만드는 것에는 한계가 있습니다. 다른 방법이 필요했습니다. 이 과정에서 유명해진 개발 방법론이 객체 지향입니다. 큰 규모의 소프트웨어를 만들 때, 객체 지향 방법론을 사용하면 훨씬 수월하게 작업을 진행할 가능성이 큽니다.

왜 객체 지향 방법이 좋냐고요😳? 이걸 다 예를 들어가며 설명하다 보면 책 한 권이 나옵니다. 그냥.. 훨씬좋다! 라고만 말씀드리겠습니다.

객체 지향이 만능은 아닙니다. 프로그램의 종류(목적)에 따라 Rule-Oriented나 Procedure-Oriented 등의 다른 접근 방식이 더 나을수도 있습니다.

객체 지향이란?

객체 지향 이전에는 프로그램을 명령어들의 목록이라는 관점에서 바라봤습니다. 소스 코드는 어떻게 동작할지를 설명합니다. 하지만 객체 지향에서는 프로그램을 객체를 중심으로 바라봅니다. 소스 코드가 이 객체가 어떻게 행동하고, 또 다른 객체는 어떤 객체와 어쩌고저쩌고.. 를 설명합니다. 계속 객체라는 단어가 등장합니다. 객체에 대해 알아볼까요?

Object (객체)

한 가지 말씀드리고 싶은 말은, 객체는 프로그래밍에서만 사용되는 컴퓨터 공학적 개념이 아니라는 것입니다.

객체는 아래와 같은 것들을 말합니다.

  1. 만질 수 있거나 보이는 것
  2. 이해될 수 있는 것
  3. 생각이나 행동이 가리키는 것

우리 주변에 있는 모든 것들이 객체입니다. 제 앞에 있는 노트북도 객체입니다. 마우스도 객체입니다. 문도 객체고요, 옆에 있는 사람도 객체입니다. 저도 객체입니다. 귀신도 객체입니다👻. 우리가 만질 수 있거나 볼 수 있는 것, 이해될 수 있는 것 모두가 객체입니다.

모든 객체는 두 가지 구성요소, 속성(Attribute)와 행동(Behavior)이 있습니다. 저라는 객체는 머리카락 색이라는 속성이 있으며, 이 속성의 값은 검은색입니다. 눈동자의 색은 검은색입니다. 저는 잠자기, 먹기, 걷기 등의 행동을 할 수 있습니다. 제 앞에 있는 핸드폰은 흰색이라는 속성을 가지고 있으며, 전원 켜기, 전원 끄기, 전화 걸기 등의 행동을 할 수 있습니다. 이렇듯 주위의 모든 객체는 속성과 행동을 가지고 있습니다.

객체 지향 프로그래밍은 이러한 객체의 개념으로 세상을 바라보고, 이것을 소스 코드로 작성합니다.

Class (클래스)

객체와 떼려야 뗄 수 없는 관계, 클래스가 있습니다.

저는 객체입니다. 사람은 클래스입니다. 제 아이폰은 객체입니다. 스마트폰은 클래스입니다. 제 눈앞에 있는 로지텍 마우스는 객체입니다. 마우스는 클래스입니다. 느낌이 오시나요? 객체는 시간과 공간에 존재하는 구체적인 실체인 반면, 클래스는 추상화, 즉 객체의 본질을 그대로 나타냅니다. 저는 존재하는 실체입니다. 따라서 검은색 머리카락, 검은색 눈동자라는 구체적인 속성값이 있습니다. 반면에, 사람이라는 클래스는 구체적인 색을 가지고 있지 않는 추상적인 개념입니다.

Procedure-Oriented vs Object-Oriented

클래스를 사용하지 않고 프로시저를 활용하여 프로그래밍 하는 방식을 Procedure-Oriented Programming이라 합니다. 객체 지향이 유명세를 타기 전에는 Procedure-Oriented 프로그래밍이 대세였습니다. 참고로 C/C++에서는 프로시저를 ‘함수’라고 말하고, 자바에서는 ‘메서드’라 부릅니다. 루틴이라고 부르는 경우도 있습니다. 프로시저 = 함수 = 메서드 = 루틴입니다.

그럼 Procedure-Oriented 프로그래밍과 객체를 활용한 Object-Oriented 프로그래밍 방법의 예를 보겠습니다. 아직 클래스 관련된 문법을 모르셔도 괜찮습니다. 그냥 대충 느낌만 느껴주세요. 저도 대충 썼습니다. 대충 콘솔에 +, - 을 입력하면 그에 맞게 speed가 늘어났다 줄어든다는 느낌입니다. C++로 작성했습니다.

  1. Procedure-Oriented Programming Example

    void drive(int &speed) {
        // console 입력을 받아서 어쩌구 저쩌구에 따라 speed 조정
    }
    int main() {
        int speed = 0;
        drive(speed);
        return 0;
    }
    
  2. Object-Oriented Programming Example

    class Car {
    private:
        int speed;
    public:
        void drive() {
            // console 입력을 받아서 어쩌구 저쩌구에 따라 speed 조정
        }
    };
    int main() {
        Car car();
        car.drive();
        return 0;
    }
    

    1번 예제와 똑같이 동작하기 위해서는 constructor에서 speed를 0으로 초기화해줘야 합니다. 문법을 모르시는 분들도 있을 테고, 중요한 내용은 아니니 가독성을 위해 생략합니다.

두 코드는 매우 비슷합니다. speed라는 변수가 있고, drive라는 함수(메서드)가 있습니다. 여기서 주목해야 할 차이점은 변수 speed의 위치입니다. 1번 에제에서 speeddrive 함수와 전혀 상관없는 곳에 떨어져 있습니다. speed가 main() 함수 안에서 선언되었든, 전역 변수로 선언되었든, drive 함수와는 전혀 상관없습니다. 그러나, 2번 예제에서는 speeddrive가 한 클래스 안에 뭉쳐져 있습니다. 이것이 보기에는 사소한 차이일지라도, 나중에는 엄청난 차이를 가져오게 됩니다. 둘은 프로그래밍을 할 때 근본적으로 다른 접근 방식입니다.

“깨끗한 코드는 잘 쓴 문장처럼 읽힌다”라는 말이 있습니다. 문장을 구성하는 요소 중 가장 중요한 것은 명사와 동사입니다. 코드에서 명사의 역할을 하는 것은 변수고, 동사의 역할을 하는 것은 함수입니다. 변수와 함수를 다루는 방식에 따라 프로그래밍 방식은 매우 많이 바뀝니다.

한 책에서는, Procedure-Oriented 프로그래밍은 동사를 중심으로, Object-Oriented 프로그래밍에서는 명사를 중심으로 코드가 구성된다고 말했습니다.

Booch, Grady and Robert A. Maksimchuk and Michael W. Engel and Bobbi J. Young, Jim Conallen, and Kelli A. Houston. 2007. Object-Oriented Analysis and Design with Applications, Third Edition. Boston, MA: Addison-Wesley.

이러한 근본적인 프로그래밍에 대한 접근 방식으로 인해, 큰 규모의 코드에서는 엄청난 차이가 나게 됩니다.

객체 지향을 배우고 싶다면

일단 클래스 관련 문법을 공부하신 후, 책을 보는 것을 추천드립니다.

  1. Object-Oriented Thought Process by Matt Weisfeld
  2. Head First Object-Oriented Analysis and Design by Brett McLaughlin, Gary Pollice, David West

보통 위의 도서 등을 추천하는 것 같군요.

객체 지향이란 개념은 쉽지 않습니다. 클래스를 설계하는 것에 정답이 없기 때문에 더 그런 것일지도 모르겠습니다. 한 번에 객체 지향을 마스터하겠다는 생각보다는, 다른 것도 배워가면서 서서히 익혀가는게 어떨까 싶습니다.

Leave a comment