Thursday, December 21, 2006

넌더리 나는 oop 얘기들...

언젠가 pattern 에 관한 스터디를 하는 도중 누군가가 물어보았다.'꼭 클래스를 써야만 oop 인가?'라는 물음이었다.
뒤이어 나오는 자신의 질문에 대한 부연설명은 class 를 사용하지 않는 언어 특히 C같은 언어로도 객체지향은흉내낼 수 있다였다.
그렇다면 이 질문은 의도는 무엇이었을까??
class를 지원하는 언어를 사용해야 꼭 객체지향인가요??아니다.
class 를 지원하는, 아니 명백히 oop를 위한 언어임이 분명한 cpp도 c 처럼 사용하고 class는 마치 c의 라이브러리와 같은 용도로 사용하시는 분을 봤다.
설마 class를 지원 하는 언어 따위는 버리고 c로 객체지향을 구현해서 쓰고 싶다는 말은 더더욱 아닐 것이다.
지금 생각해보면 그 질문의 의도는 객체지향은 이래야 한다는 이런 저런 말들에 대한 지쳤다는 말의 다른 표현인 듯 싶었다.
class 들이 그 도마 위에 오른 것은그런 논의들이 class를 위주로, class 들간의 관계는 이래야 하며, 저래야 하며... 처럼 돌아가기 때문 인 것 같았다.
우선 그 질문에 대한 나의 대답은 no 라고 하고 싶다.
만약 그 질문의ㅡ 대답이 yes 라면 왜 굳이 oop(object oriented programming) 이라고 지었겠는가?그냥 cop(class oriented programming)이라고 지었겠지.
그 질문에는 이런 의미도 포함되어 있었던 듯 하다. '나는 object라는 것은 인정하지만, class란 건 인정못하겠습니다.'
맞는 말이다. structure 를 사용하건 class 를 사용하건 object(객체)라는 개념이 사용된다면 객체지향 이라고 볼 수 있지 않을까 한다.

내가 처음 짜본 oop 프로그래밍은 채팅서버였다. 이 채팅서버라는 세계를 채우고 있는 object는 room(채팅방), client(채팅방으로 접속하는 놈) 가 전부였다. 당장 c의 statement 나열형으로 만들어 놓은 것을 oop로 다시 설계하려니 머리 속에 떠오르는 놈은 그게 전부였다. 그렇게 만들어 놓은 놈을 선배에게 창피한 마음에 주저주저하며 보여줬다. (암것도 안 들어 있는 내 머리속을 보여주는 듯 하여...) 하지만 선배의 말은 '잘했어. 기본적으로 oop라는 개념이 들어간거잖아.' 라는 대답이었다. 하지만 지금 그 프로그래밍을 보면, capsulation 같은 건 별로 고려되지 않은 그냥 데이터와 함수의 집합에 불과해 보이는 조잡한 프로그램에 불과하다.

oop를 무엇이라고 생각하냐고 물어보면 내공이 많이 된 사람들의 입에서 나오는 얘기는 그것이다.
감추기(hiding)!!
얘가 무슨 놈을 가지고 있고 한 가지 명령을 내리면 세부적으로 어떤 동작들을 하는지를 모르게 한다는 것이다. 내가 세상을 100% 꽤뚫어 보며 살아야 생활이 가능한 것이 아니듯 oop 세계에서는 남이 무슨 일을 하건 세세한 사항까지 알아야 하는 것이 아니라는 것이다. 다만 그 일을 계승(inheritance)한 자만 그 사정을 이어 받으면 된다.
하지만 oop 라는 것을 처음 설계했을 때 부터 hiding 이 oop 의 핵심개념이다!! 라고 명확하게 인식 하고 있었을까? 처음에는 분명 내가 채팅서버를 만들 듯 사용되었을 것이라 생각된다. 어떤 객체가 있고 이것이 하는 일들이 있는 것처럼, 마치 역할 수행자들처럼 구조를 만들면 어떨까?? 하는 식으로 말이다.


그냥 단순히 statement를 나열한 것 보다 함수를 이용해서 쪼갰을 경우의 이점은 무엇인가? 중복을 막을 수 있다는 것이 첫번째라면,
어느 한 가지 일을 하는 부분을 함수로 나누어 놓는다면 우리는 그 부분을 별도로(unit) 생각할 수 있다
예를들어 strcat 같은 함수가 제공되지 않고(물론 이 함수가 구조적으로 미숙하다는 점을 배제했을 경우. 즉 이 함수가 엄청난 편리성을 제공해준다고 할경우) 매번 아래와 같은 소스를 코딩해줘야 한다고 생각해보자.
{
...
char a[100];
char b[100];
...
while(*a) *a++;
while(*a++ = *b++);
...
}
이 소스 부분을 볼 때마다 우리는 정확한 결과를 알아내기 위해 쉴새없이 머리를 굴려야 한다. 몇 분 동안의 고민뒤에 이 부분이 a 의 뒤에 b를 연결하는 것이라는 것을 알아낸다. 한 번은 몇번에 불과하지만, 이러한 코드가 여러군데 산재해 있다면, 계속해서 시간이 추가된다. (물론 여러번 읽으면 읽을 수록 익숙해지겠지만, 이건 사법고시 수험서도, 자꾸만 읽고 싶어지는 시구도 아니다. 게다가 이것은 너무나도 간단한 함수의 예가 아닌가.)

하지만 이 부분을 strcat이라는 unit으로 묶어 둠으로써 한 눈에 이 부분이 어떤 작업을 하는지 알아낸다. 이로써 우리 머리속의 논리흐름에서 하나의 작은 분기점이 없어진다. 게다가 strcat이 unit test를 잘 통과하기만 한다면, 우리는 어느정도 안심하고 strcat을 신뢰하면서 디버깅을 해나갈 수 있다.
결국 structure나 함수라는 것이 도입된 것은 인간의 논리적 본성 즉 분류하기에서 기인했다고 볼 수 있지 않을까? 그 본성이 발전하여 결국에는 oop가 된다. 분류해 놓은 작업들을 소유한 사람들이 있었으면 좋겠다. 이것 역시 분류다.

"집안에는 할 일이 많아요. 넓은 집을 청소해야 하고, 식사도 마련해야 하며, 정원도 관리해줘야 하죠. 아이들을 돌봐야 하고 자동차를 몹니다. 종종 인테리어를 바꿔주기도 하며 개를 기르기도 합니다. 이 애완동물을 키우기란 꽤나 귀찮은 작업인데 배설물을 치워줘야 하며 먹이도 주고 규칙적으로 산책도 시켜줘야 하죠. 또 가계경제는 왜 그렇게 골치 아픈지..."
이 사람은 모든 일을 자신이 알아서 했다. 필요할 때 마다 머리 속에서 자신이 해야 할 일들의 방법을 생각하며 집안일을 수행하곤 했다. 다행히 그의 머리 속은 체계적으로 잘 정리가 되어 있고, 어려운 부분들은 차분하게 메모를 해 놓는 편이라 그럭저럭 잘 해나갔다.
어느 날 이 사람이 직장에서 승진을 한다. 수입은 더 좋아졌지만, 자신이 생각해야 할 일들이 너무 많아서 집안일을 일일이 해나가기가 너무 힘들다. 그래서 고용인을 구하기로 한다. 고용인 3명(3명인 이유는 집안일이 너무 많아서 이 정도 인원이 필요하다고 생각되기 때문이다.)을 구해서 집안일을 맡긴다.
집안일은 이 사람이 자신이 하던 집안일들을 체계적으로 매뉴얼화 한 것을 고용인들에게 나누어 주고 일일이 지시하기 시작했다. 'A씨는 지금 애를 봐주세요. B씨는 개를 산책시키고, C씨는...)' 이런식으로 일을 시키고 모든 일을 다 수행했다고 보고 하면 그 때 그 때 하는 일들을 다시 정해주었다. 하는 일들은 모두 각자 가지고 있는 매뉴얼에 나와 있고, 이 사람은 지시만 하면 방법은 그들이 각자 보고 하는 식으로 진행되었다.
몇 번의 반복으로 인해 이 사람은 한가지 사실을 터득한다.
집안일을 3등분 하여 3명에게 담당을 하도록 하는 것이다.
이렇게 하면 그는 이 한마디로 지시를 내릴 수 있다. '오늘 할 일을 하도록 하세요.'
게다가 가장 중요한 것은 가끔 일어나는 불상사에 대한 책임소재를 확실히 할 수 있었다. 아이가 독감에 걸렸을 때 독감예방접종 시기임에도 불구하고 그 책임을 방관한 사람이 누구인가, 자신의 주식투자가 손해를 보고 있는데, 어떤 사람이 재무관리 쪽을 맡아서 이런 손해가 나는 투자를 했던 것일까 하는 것에 대해 책임소재가 분명해진다. 반대로, 가끔 이 사람이 무슨 일을 하는 사람인지 알 고 싶을 때는 그 사람의 명세서를 보면 된다. 흠, D씨는 청소와 음식을 맞고 있군.

그러다가 청소와 음식을 같이 하는 사람이 음식과 청소를 병행하다 보니 위생적관리에 있어서 문제점을 보인다. 그래서 지출이 더 커지겠지만, 한 사람을 더 고용하여 주방에 관련된 일만 하도록 맡긴다.

바보 같은 인물이긴 하지만, 이 인물은 바로 프로그래머다. 가장 현명해 보이는 상황이 이런 상황들을 거쳐서야 나오다니. 하지만 software developement의 역사도 이렇게 조금씩 순차적으로 발전되어 왔을거라고 본다. 단순하 일련의 기계어의 연속에서 loop, 함수, structure, class. paradime 은 점점 책임나누기로 진화해왔다. 이 진화의 이유는 단 하나.
인간이 사용하기 편하게!!
복잡해진 환경, 그러나 그 환경에 맞추어서 분화시키기에도 낮아진 상대적 비용. 두가지가 맞물려서 개발자라는 인간들이 좀 더 편리하게 그래서 좀더 가치있는 많은 것들을 하도록 발전해 간다.


oop 건, statement 형식의 프로그래밍이건...결국 컴퓨터가 보기에는 똑같다.
단순히 0과1의 나열, 아니 전기가 들어오고 안들오고의 차이 일뿐 아무것도 아니다.
결국 '왜 꼭 클래스를 써야 하나요? 저는 statement 방식이 좋습니다'하는 것은 어찌보면, '저는 기계어를 아주 잘 읽습니다. 아니 사실은 저는 트랜지스터에 전기가 들어오고 나가는 것을 느끼곤 하지요.' 라고 하는 말과 비슷하다.
물론 50억 인구중에 이런 특출난 로봇지향형 인간이 있을 수 도 있다. 하지만, 동료들은 이렇게 말하지 않을까?.
'이런이런.. 저는 기계어는 해독 불가입니다. 옆에 해석자가 따로 있어야 하지요. 어쩔 수 없어요 제가 한국에서 태어난 이상 영어가 저에게는 어렵듯이 기계어를 보고 풀이할 수는 있을 지 모르지만, 기계어 맵을 봐야 할걸요...게다가 c 정도 수준으로 까지 이해하려면...흠... 아마 저에게 그런 능력이 있어야 한다면, 저는 밥을 굶어야 할지도...'
결론은 단 한가지. 인간의 편의를 위해 만든것이라는 것. 마치 자동차나 계산기 처럼...주판도 역시나...

1 comment:

Mini said...

OO 를 한문장으로 라고 표현한 건방지지만 하나도 틀린게 없는 글OO in one sentence
Tell, Don't Ask

내가 생각하는 OO 의 기본은 하나의 명확한 책임을 하나의 객체가 가지는 것

Io 같은 prototype 언어는 class 가 없고 모든 것이 object. 중요한 것은 OOP 적인 사고를 하고 있다면, C 던 어떤 언어로도 OOP 를 할 수 있고, 잘 설계된 OO 언어는 OOP 적인 사고를 도와 줄 수 있음(단, 보장해 주지는 않음).

Hiding, 무엇을 hiding 하느냐 보다는 왜 hiding 할까? 왜 위임이 상속보다 좋을까(delegation over inheritance)?

About Me

Hostway Korea R&D Center