객체지향 프로그래밍의 의미
어떤 의미에서 객체지향 프로그래밍(Object Oriented Programming, 이하 OOP)은 이전까지 함수 단위로 나눠 관리하던 소스 코드를, 이제 객체라는 보다 큰 단위에서 관리하려는 시도라고 볼 수 있다. 실제로 OOP는 소스 코드의 복잡성을 관리하는 매우 효과적인 방법이다.
함수 단위의 코드 작성에는 몇 가지 현실적인 문제들이 존재했다. 첫 번째로 함수의 네임 스페이스를 관리하는 문제를 꼽을 수 있다. 예를 들어 배열의 사이즈를 계산하는 함수가 필요하다고 가정해보자. 처음에는 이 함수에 그냥 get_size()라는 이름을 붙여도 별다른 문제가 없다. 하지만 시간이 흘러 이제 파일 버퍼의 사이즈를 계산하는 함수가 추가로 필요하게 되면, 조금 애매한 상황이 연출된다. 이전의 함수와 새 함수는 유사한 기능을 가지고는 있지만, 서로 인자로 취하는 데이터 타입이 달라 이 두 함수의 이름을 구분해야만 하기 때문이다.
이런 상황에서는 get_array_size(arr)나 get_file_buffer_size(fb) 등과 같이 접두어(Prefix)를 써서 두 함수의 이름을 구분하게 된다. 다른 종류의 데이터 타입에서도 사이즈를 계산하는 함수는 필요하게 마련이므로, 이와 비슷한 이름을 가진 함수의 개수는 계속해서 늘어날 것이다. 특히 여러 개발자와 공동 작업을 하고 다양한 외부 라이브러리를 사용하다 보면 비슷비슷한 이름의 수많은 함수들을 기억하고 사용하는 일이 상당히 어려워져, API 문서를 참고하지 않고서는 간단한 코딩 작업도 힘들게 될 것이다. 여기에 함수 자체의 소스 코드를 수정할 일까지 생기면, 이제 각 함수가 어느 파일에서 정의되고 있는지를 기억하고 관리하는 것은 더욱 만만치 않은 일이 된다.
그런데 ‘get_file_buffer_’와 같은 긴 접두어를 타이핑하는 것에 지친 어느 개발자가 다음과 같은 멋진 생각을 해냈다. ‘get_file_buffer_size()’는 파일 버퍼 데이터에만 사용될 수 있는 함수이니, 차라리 그냥 파일 버퍼 데이터에 이 함수를 묶어버리면 어떨까? 이 생각을 그대로 실천하니, 다음과 같은 코드가 등장했다.
arr.size();
fb.size();
함수를 데이터에 묶어버림으로써, 그 함수가 어떤 데이터 타입에 적용되는지를 이제 함수 이름에 표시할 필요가 사라졌다. 데이터가 특정 함수를 호출하는 데 일종의 네임 스페이스의 역할도 맡게 된 셈이다. 결과적으로 함수의 이름이 상당히 간결해졌고, 같은 종류의 기능을 수행하는 모든 함수에 동일한 이름을 붙이는 것이 가능해졌다. 게다가 데이터 타입과 함수간의 관계가 보다 밀접해져서, 이제 데이터 타입이 정의되는 곳에서 함수를 함께 정의하는 것도 자연스러워졌다. 이와 같은 변화는 궁극적으로는 전체 소스 코드의 구조를 보다 단순하고 직관적으로 만드는 데 결정적인 기여를 했다.
상속, 다형성, 캡슐화 ≠ OOP
이러한 새로운 프로그래밍 방식을 구분하기 위해서 개발자들은 함수가 함께 묶인 데이터를 ‘객체’라고 불렀고, 데이터에 묶인 함수에 ‘메소드’라는 새로운 이름을 부여했다. 아울러 데이터 타입이란 표현 대신에 ‘클래스’란 용어를 쓰기로 약속했다. 이제 프로그램을 함수 단위가 아니라 객체 단위에서 설계하고 이해할 수 있게 된 것이다. 객체 단위에서 프로그램을 작성한다는 의미에서 자연스레 ‘객체지향 프로그래밍’이란 용어도 생겨났다.
상속, 캡슐화, 그리고 다형성 등은 이 새로운 프로그래밍 패러다임을 체계화하는 단계에서 도입된 개념으로 코드의 재활용을 증가시키고 소스 코드의 일관성을 개선하는 데 큰 역할을 했다. 하지만 이들 개념이 의미하는 바가 OOP의 본질이라고 말하기에는 다소 애매한 부분도 있다. 예를 들어 자바스크립트와 같은 일부 OOP 언어에서는 상속의 개념이 적용되지 않고, OOP 언어의 원조로 여겨지는 SmallTalk나 루비 등에서는 다형성 대신 덕 타이핑(Duck Typing)이란 개념이 쓰이고 있다. 마찬가지로 캡슐화는 OOP만의 특징이라기보다는 프로그래밍의 보편적 개념인 추상화(Abstraction)의 예로 이해하는 것이 타당할 것이다. 상속과 다형성 등이 C++와 자바를 포함한 여러 OOP 언어의 핵심 기능임에는 틀림없지만, 이들 자체가 곧 OOP를 의미하는 것은 아니므로 이 글을 계기로 개발자들이 OOP의 의미를 한번쯤 되짚어 보길 바란다.
노트: 이 글은 마이크로 소프트웨어 2007년 1월호에 "마소플러스: 객체지향 프로그래밍의 의미"라는 제목으로 실렸습니다.

