Posted by 大山
Thu, 17 Aug 2006 07:56:00 GMT
[참고: 이 글은 객체지향 프로그래밍에 대한 오해와 진실에 이어지는 시리즈임.]
객체지향 언어에 대한 입문서를 보면, 상속, 캡슐화, 다형성 외에도 빠지지 않고 등장하는 설명이 하나 있다. 바로 객체는 실제 세상(Real World)의 물체를 모델링한다는 것이다. 물론 이 내용을 다루는 챕터는 모든 객체가 실제 세상의 물체와 대응될 필요는 없다며 어물쩍 마무리를 하기 마련이지만 말이다.
실제 세상에 대한 모델링이란 주장은 얼핏 객체의 필요성에 대한 그럴듯한 설명인 것 처럼 보이지만, GUI 프로그래밍이나 시뮬레이션 설계를 하는게 아니라면 전혀 맞아들어가지 않는 설명이다. 오히려 이 때문에 일부 뛰어난 해커들마저 OOP를 오해하는 경향이 있기 때문에 여기서 짚고 넘어가려고 한다.
객체지향 프로그래밍에 대한 또 한가지 오해는 상속이 코드 재사용의 핵심이라는 말이다. 이는 다분히 과장된 주장이라고 보여진다.
마지막으로 모든 객체지향 언어에 해당되는 것은 아니지만, 많은 개발자에게 '객체지향 언어 == C++ 또는 자바'로 받아들여지므로 이 내용을 같이 다루어도 좋을 성 싶다. 바로 스태틱 타이핑(Static Typing)이 버그를 줄여준다는 오해이다.
하나씩 짚어보자. 어쩌다가 객체지향 언어는 실제 세상의 물체를 모델링한다는 설명이 생기게 되었을까? 바로 최초의 객체지향 언어였던 Simula가 시뮬레이션 용으로 만들어진 언어였기 때문이다. 하지만 여기서 주의할 점은 Simula는 1960년대에 나온 프로그래밍 언어였다는 점이다. 실제로 1971년에 나온 Smalltalk-71은 Simula에서 객체에 대한 메세지 보내기 개념(즉 데이타와 함수를 묶어두는 방식)만 따와서 구현된 것으로 알려져 있다.
시뮬레이션 또는 GUI 프로그래밍에서는 객체지향 프로그래밍이 무척이나 자연스럽게 느껴지는 것이 사실이다. 하지만 프로그래밍의 범주는 이보다 훨씬 더 넓고, 객체지향(데이타에 함수 묶어두기) 프로그래밍은 꽤나 보편적으로 유용하다.
두번째로 상속과 코드 재사용성 부분인데, 상속을 통해서 코드 재사용을 추구하는 것은 프레임워크에서 제공하는 템플릿 클래스를 사용하는 등의 상당히 제한된 경우에만 적합한 것 같다. 이 때문에 Objective-C를 사용하는 Cocoa 같은 프레임워크에서는 조합(Composition)과 위임(Delegation)의 사용을 훨씬 더 강조하고 있다.
그런데 왜 상속을 통한 코드 재사용이 그토록 강조되는 것일까? 아마도 마케팅의 영향이 아닌가 싶다. C++와 자바는 모두 업계 주도적으로 확산된 언어이다. 마케터들은 실제로 중요한 것 보다는 사람들의 머리속에 각인될만한 내용으로 마케팅을 전개하기 마련이다. 이 마케팅이 너무 성공적이어서 수많은 개발자들을 헤매이게 만들기는 했지만 말이다.
마지막으로 스태틱 타이핑 부분인데, 스태틱 타이핑이 컴파일 최적화에 도움을 주기 때문에 프로그램의 성능을 높여주는 것은 사실이다. 무어의 법칙때문에 나날이 덜 중요해지는 요소이기는 하지만 말이다. 하지만 스태틱 타이핑이 개발자의 실수를 방지해서 버그를 줄여준다는 말은 낭설에 가까운 것 같다.
스태틱 타이핑의 옹호자들에게 물어보라. 당신들은 스태틱 타이핑이 자신들의 실수를 줄여준다고 생각하느냐고. 그들은 이렇게 말한다. 자신들은 그런 초보적인 실수를 안하지만, '평균'적인 개발자에게는 그런 안전장치가 필요할 것이라고. 사용자들이 멍청할 것이라고 가정하는건 개발자들이 범하는 가장 흔한 실수 중의 하나이다. 일부 프로그래밍 언어의 설계자들 역시 비슷한 오류에 빠졌던 것은 아닌가 싶다.
Posted in 프로그래밍 | Tags 프로그래밍, OOP | 12 comments | 1 trackback
Posted by 大山
Wed, 16 Aug 2006 08:14:00 GMT
많은 개발자들이 OOP(객체지향 프로그래밍, Object Oriented Programming)를 처음 접하는 것은 아마도 C++나 자바를 통해서일 것이다. 보통 C++/자바 입문서는 OOP란 무엇인가를 설명하는 챕터로 시작되기 마련인데, 하나같이 객체지향 프로그래밍의 핵심을 상속(Inheritance), 캡슐화(Encapsulation), 다형성(Polymorphism)이라고 설명하고 있다.
나중에 Objective-C, Smalltalk, 자바스크립트 등을 접하면서 이같은 설명이 얼마나 엉터리인지 깨닫게 되었다. 이 글에서는 내가 지난 수년간 객체지향 프로그래밍에 관해서 이해하게 된 것을 한 번 정리해 보려고 한다.
조금 규모가 있는 프로그램을 작성하다 보면, 가장 골치아픈 이슈 중의 하나가 소스코드의 복잡성을 관리하는 문제이다. 변수와 함수의 이름을 일관적으로 정리하고 전체 소스코드에 체계적인 구조를 잡아두지 않으면, 자신이 직접 작성한 코드를 들여다 보는 것 조차 막막해지기 십상이다.
프로그래밍 언어는 이러한 소스코드의 복잡성을 보다 체계적으로 관리할 수 있는 방향으로 발전해 왔다. 초기의 프로그래밍 언어에는 함수 개념 조차도 빠져 있었다. 함수는 프로그램을 유닛 단위로 나누어서 관리하기 위해 만들어진 가장 기초적인 개념이다. 루프, 조건문, 케이스문 등 역시 프로그램을 보다 체계적으로 작성하기 위해 생겨났는데 과거에는 이들 대신에 GoTo문이 사용되곤 했었다.
그런데 점차 프로그램에서 사용되는 함수의 수가 늘어나자, 함수의 이름과 그 소스코드를 관리하는 일이 커다란 문제가 되어버렸다. C나 PHP로 개발을 해 본 사람은 잘 알겠지만, mysql_field_name(), mssql_field_name() 식으로 함수 이름 마다 접두사(Prefix)가 필요한 데다가, mb_strlen(), ob_get_length(), mysql_fetch_lengths() 처럼 함수 이름을 명명하는 방식은 개발자마다 제각각이게 마련이다. mailparse_determine_best_xfer_encoding() 처럼 함수 이름이 한도없이 길어지는 문제는 두말할 필요도 없겠다.
객체지향 프로그래밍은 바로 이러한 문제에 대한 해결책을 제시했다. 함수를 아예 데이타에 묶어서 관리하면 그 이름이 짧아지게 될 뿐더러, 함수의 소스코드 또한 데이타 구조의 정리체계에 따라 관리가 가능하다는 것이 바로 객체지향 프로그래밍의 핵심이다. 객체지향 프로그래밍에서는 이렇게 데이타에 묶여진 함수를 메소드(method)라고 부른다.
물론 데이타에 묶어서 관리하는 것이 자연스럽지 못한 함수도 적지 않은게 사실이다. OOP 언어에서는 데이타(객체)에 묶어두기에 적합하지 않은 함수를 클래스나 모듈에 묶어 관리하는 방식으로 이 문제를 비켜가고 있다. 클래스는 함수 이름 관리를 위한 적절한 네임스페이스를 제공해 주기도 하기 때문에, 객체에 묶이지 않은 함수의 경우에도 함수 이름과 그 코드의 관리가 한결 수월하게 되었다.
이 글의 시작에서 언급했던 내용을 다시 한 번 살펴보도록 하자. OOP를 설명하는 일반적인 방법은 상속, 캡슐화, 다형성 등의 개념을 통해서이다. 그런데 캡슐화란 프로그래밍에서는 너무도 보편적인 개념인 추상화(Abstraction)의 또다른 표현일 뿐이고, 다형성은 함수 이름에서 접두사(Prefix)가 빠진다는 것을 어려운 용어로 표현한 것에 불과하다. 상속 조차도 객체지향 시스템을 설계하는 하나의 방식에 불과해서, 자바스크립트 같은 언어에서는 상속 대신 프로토타입(Prototype)이라는 전혀 다른 개념을 사용하고 있다.
객체지향이란 함수를 관리하는 하나의 프로그래밍 기법에 불과할 뿐이다. 매우 효과적이고 편리한 방법임에는 틀림이 없지만, 그렇게 거창하지도 또 이해하기에 복잡한 개념도 아니다.
관련글: 객체지향 프로그래밍에 대한 오해와 진실 2
Posted in 프로그래밍 | Tags 프로그래밍, OOP | 9 comments | 1 trackback