SmalltalkObjectsandDesign:Chapter 01

From 흡혈양파의 번역工房
Revision as of 13:07, 4 August 2013 by Onionmixer (talk | contribs) (wiki 형식수정)
Jump to navigation Jump to search
제 1 장 객체

객체

객체 지향 프로그래밍에서 핵심 개념은 물론 프로그래밍 객체이다. 첫 장에서는 먼저 이 개념을 살펴보면서 스몰토크를 약간 소개하고자 한다. 하지만 당장 스몰토크 조각(fragment)의 세부 사항에 말려들지는 않기를 바란다; 그러한 조각들의 목적은 개념을 설명하는 것이다.


객체

객체

프로그래밍 객체는 어느 정도의 연산(operations)과 어느 정도의 정보를 갖는다. 우리는 종종 프로그래밍 객체를 좌측의 은행계좌 객체 그림과 같이 "도넛"으로 표현한다. 당신이-"고객이"-이 객체를 사용하고 싶다면, 그것을 실행하는 데에 필요한 3가지 연산을 인식해야 한다: 즉, 통장 잔고를 알려주거나, 일부 금액을 인출하거나, 아니면 일부 금액을 입금하는 동작(operation)을 의미한다. 그거면 충분하다. 심지어 당신은 $150가 객체 내부에 편안하게 자리잡고 있다는 사실도 알 수가 없다. 그 정보는 객체 내에 private으로 유지되며, 당신의 시선으로는 접근이 불가하다. 따라서 당신의 관점을 좀 더 정확하게 나타내는 그림을 아래에 소개하겠다.

프로그래밍 객체

프로그래밍 객체란, 당신이 요청할 수 있는 연산으로 구성된 외부(outside)와 그에 반해 객체의 연산에 의해 사용 가능한 정보를 당신에게 숨기는 내부(inside)를 가진 것으로 정의할 수 있다. 당신은 외부는 볼 수 있지만 내부는 볼 수 없다. 이 개념을 소프트웨어 공학 용어로 캡슐화라고 한다: 객체의 내부는 객체의 연산에 의해 캡슐화된다. 일반적으로 데이터는 내부에 위치하고 연산은 외부에 존재한다. (물론 이러한 규칙을 원치 않는 경우도 목격하겠지만, 당장은 경험에 근거한 규칙이다.)

가령 계좌의 잔고와 같이 객체 내부에 관해 정말로 알고 싶은 경우가 발생하면, 객체의 연산들 중 하나를 이용하여 간접적으로만 얻기를 희망할 수 있다. 이번 예제에서는 누군가 balance(잔고) 연산을 호출하면 객체는 자신이 $150를 포함하고 있다고 알림으로써 응답하길 원한다고 치자. 표기법을 주목하라: deposit:withdraw: 다음에는 콜론이 붙지만 balance 뒤에는 붙지 않는다. 이것은 스몰토크의 특이점이다. 이는 연산이 argument를 필요로 함을 나타내는 편리한 방법이다-계정에서 돈을 인출하거나 입금할 때는 금액을 명시한다; 잔고를 요청할 때는 금액을 명시하지 않는다.

객체

프로그래밍 객체를 개념화하는 또 다른 방법은 객체를 작은 사람으로 생각하는 방법이다: 이 작은 난쟁이(homunculus)에게 (라틴어에서 유래, man+little) 그의 연산 중 어떤 것이든 수행하도록 요청할 수는 있지만 그가 그것을 어떻게 실제로 구현하는지나 그것을 구현하기 위해 자신의 내부에서 무엇을 사용하는지 당신은 알지 못한다. 객체의 연산을 설계할 때는 객체를 작은 사람으로 생각하고, "현명하고 작은 계정 객체는 어떤 능력을 가져야 하는가?"라는 의문을 품는 데에 어색해해선 안 된다.

이렇게 뻔뻔한 의인화된 질문은 어떻게 보면 치사한 속임수처럼 들릴지도 모른다. 하지만 은유법-필자는 형상화(imagery), 직유(simile), 비유(analogy)도 포함시킨다-은 강력한 인지도구이다. 은유는 한 영역에 대해 (예: 사람들) 이미 알고 있는 내용을 이용해 덜 알려진 영역에 관한 (예: 은행업무 소프트웨어) 생각을 규명하도록 해준다. 이러한 장치는 "계좌(account)는 돈을 나눠주거나 그가 돈을 얼마나 갖고 있는지 나에게 말해줄 수 있을 만큼 똑똑해야 한다,"와 같은 말을 할 수 있도록 장려한다. 사실 오리지널 스몰토크인 Smalltalk-72에서 프로그래밍 객체의 개념은 생물학적 세포에 대한 은유를 이용했다 [Kay 1988]. 이와 같은 형상화가 물론 "Shall I compare thee to a summer's day('나 이제 그댈 여름날에 비하리까?'라는 윌리엄 셰익스피어 소네트입니다)"에 필적하지 않을지는 모르지만 이해는 할 것이다 [Shakespeare 1609].

이제 객체가 무엇인지 이해했을 것이니 객체의 이용과 관련된 사고방식을 발전시켜보도록 하자. 객체에게 그의 연산 중 하나를 수행하도록 "요청"하려면 당신은 메시지를 전송해야 할 것이다. 이 때 모든 사람은 거만하게도 메시지가 무엇인지 객체가 이해할 것이라고 가정하는데, 이는 사람들이 그것에 대해 깊이 생각해보지 않았다는 증거이다. 문제는 그 "메시지"가 많은 개념들을 함축한다는 점이다. (이메일 메시지일까? 아니면 귓속말(Whisper)? 응답기계에 있는 것? 포스트잇? TCP/IP 패킷?) "메시지"는 너무나 추상적인 한 단어이다. 좀 더 나은 단어로 전보(telegram)가 있다. "전보"는 가시적이다: 만질 수도 있고, 그것이 전송하는 정보를 볼 수 있으며, 그것이 수신인 대문에 도착하는 순간을 그릴 수도 있다. "메시지"와 같이 모호한 전자 음향이 아니다. 따라서 필자는 "메시지"라는 용어를 읽을 때마다 구식 전보를 생각하길 권한다.

메시지는 정보 무더기를 가지는데, 이는 연산의 이름과 그것이 필요로 하는 arguments로 구성된다. 예를 들어, account 객체에서 $50를 인출하기 위해서는 해당 객체로 메시지를(또는 전보를)-withdraw: 50-전송할 것이다.

객체


유휴 상태였던(dormant) account 객체는 깨어나는 즉시 withdraw: 연산의 실행을 시작한다. 이제 흥미로운 일들이 전부 발생하면서 모든 유형의 효과를 미칠 수 있다. 예를 들어, account 객체는 다른 객체들로 차례차례 메시지를 전송할 수 있는데, 은행 감사를 위한 보고서를 첨부하는 효과가 추가될 수도 있다. 아니면 그 외에 account 객체 내 숨겨진 $150가 $100로 떨어진다는 점을 제외하면 흥미로운 일이 발생하지 않을지도 모른다. 하지만 결국 account 객체는 withdraw: 의 실행을 완료하고 객체를 당신에게 리턴한다. 어쩌면 receipt(영수증) 객체일지도 모른다. 그것이 무엇이든 당신이 기다려온 대상이다. 당신이 메시지를 전송하였고, 어떤 결과를 예상했으며, 이제 결과를 얻었으니 무언가 실행할 준비가 된 것이다.

스몰토크에서 reiterate:로 메시지를 전송하는 경우, 언제나 일부 객체가 당신에게 리턴된다.. 리턴된 객체가 흥미롭지 않을 수도 있지만 당신의 필요 유무와 관계없이 항상 하나를 얻을 것이다. 어떤 메시지의 결과든 두 가지를 생각해야 한다: 첫째, 무언가 발생-연산은 그 효과를 미친다-한다는 점과, 둘째, 실행 끝에 일부 객체가 리턴된다는 점이다. 효과와 리턴을 기억하라.


프로그래밍 객체에 꽤 간단한 후보를 소개하겠다:

  • 방금 보았듯 입금, 인출, 잔고 문의를 위한 연산이 있는 은행 계좌.
  • 엔트리의 추가나 삭제, 업데이트를 위한 연산이 있는 사전(dictionary).
  • 표시, 크기조정, 이동 등의 연산이 있는 사용자 인터페이스 내 창(window).


(1980년대 초의 일부 언어들은 이와 같이 프로그래밍 객체를 정의하기 위한 특별한 구문을 갖고 있다. 예를 들어, Ada에서 package 또는 Modula-2에서 module을 사용할 수 있다.)

프로그래밍 객체에 대해 좀 더 특이한 관점으로 7과 같은 정수를 들 수 있다. 스몰토크는 "모든 것은 객체다,"라는 원칙을 수용한다. 따라서 다른 객체 지향 언어와 달리 스몰토크는 정수 또한 객체라고 주장한다. 이러한 주장이 무해하게 들릴지도 모르지만 사실 산술에 대한 기존의 이해에 도전장을 제기한다.

아래와 같은 표현식을 생각해보자:

7 + 4


결과가 11일 것이라 예상되며:

4 + 7


위와 같은 순서를 바꿔 계산해도 동일한 결과가 생산될 것이라 예상한다. 우리는 초등학교 때부터 이 표현식이 대칭 방식으로 행위할 것이라 예상하도록 훈련받았다. 우리 중 일부는 이러한 대칭을 설명하기 위에 "덧셈(addition)은 가환성(commutative)을 만족한다"와 같은 구호를 외우고 다녔다. 우리는 덧셈을 공부하고 있었고, 덧셈 기호에 집중했다.

객체의 관점에선 다른 것을 강조한다. 즉, 정수 7이 객체일 경우 초점은 바뀔 것이다; 7이 훨씬 더 흥미로워지고 + 기호의 흥미도는 훨씬 떨어진다. 따라서 아래와 같은 일이 발생한다:

객체의 관점


메시지 +4 가 7 object에 부딪치면, 그 곳에서 덧셈 연산이 실행되어 최종적으로 다른 정수 객체인 11을 리턴한다. 초등학교 때 느끼던 대칭적인 느낌은 없음을 주목한다. 대신, 7 object 가 주역을 한다. +4라는 이름이 붙은 메시지에 응답할만큼 충분히 똑똑한 주체는 바로 난쟁이(homunculus)이다. 그것은 +를 자신의 연산들 중 하나로 인식하고, +와 함께 argument가 동반할 것으로 예상하는데, 여기서 argument는 4가 된다. 그것은 연산을 실행하고, 결국 메시지가 전송된 곳으로 object 11을 리턴한다. 다행히 초등학교에서 배운 답과 동일하다. 하지만 이 답을 얻기 위해 사용한 추리의 방향은 초등학교에서 배운 내용과는 다르다. 대칭이 사라지고, 관심의 중심이 연산(+)에서 객체(7)로 전환된다.

많은 사람들이 이러한 산술 모델을 달갑지 않게 생각한다. 필자의 거리낌없는 친구들 중 한 명은 스몰토크 프로그래머는 아니지만 이와 같은 방법을 "소수 과격파"들의 (1970년대 초 스몰토크 비평가들도 사용한 이름) 음모라고 맹렬히 비난했다. 이 방법의 유일한 장점은 일관성으로 보인다: 은행 계좌나 사전과 마찬가지로 정수는 또 다른 유형의 객체로, 다른 객체들처럼 메시지에 의해 활성화된다. 스몰토크에 대해 더 들을수록 스몰토크는 누가 좋아하든 싫어하든 가장 완강하게 일관성을 유지하는 소프트웨어 시스템들 중 하나라는 것을 깨달을 것이다. 따라서 정말 모든 것이 객체가 될 것이다.

소수 과격파에 관한 논의를 접어두기 전에 argument 4는 어떻게 할까? 필자는 앞서 리턴된 11 또한 (정수) 객체라고 언급한 바 있다; 그렇다면 argument도 객체일까? 물론이다. 리턴값은 물론이고 argument도 스몰토크에선 객체이다. 모든 것은 객체다.

이제 정수와 같은 객체와 은행 계좌와 같은 객체 간에 개념적 차이가 한 가지 있을 것이다. 7 객체의 의 내부를 생각해보자. withdraw: 50 전보 이후에 은행 계좌 내부의 잔액이 바뀌듯이 +4 전보 이후에 7 객체 내부도 바뀌어야 할까? 그 문제와 관련해서는 정수 객체 내부에 무엇이 있는지부터 생각해야 한다. 내부를 특별한 7-ness 질(quality)이라고 생각해보자-정확한 비트와 바이트는 중요하지 않다. 이러한 질이 바로 7이 +4에 대해 13이 아닌 11로 응답하게 만든다. 그 외 누구도 그러한 질을 가지지 않는다. 여기서 7-ness는 절대 변경되지 않는다; 추후에 7로 +19 전보를 전송하면 우리는 그것이 26으로 응답할 것이라 자신한다. 내부가 변경 가능한 accounts 같은 가변(mutable) 객체와 반대로 정수와 같은 객체들은 변경이 불가하다(immutable)-따라서 절대로 변경되지 않는다.


스몰토크 메시지의 (전보) 예제

스몰토크에서 일반적인 경험 법칙은 표현식을 좌측에서 우측으로 파싱하는 방법이다. 아래를 고려해보자:

9 talk

이 구문은 대부분의 프로그래밍 언어의 구문과 다르다. 즉 talk라는 이름의 메시지를 object 9로 보내고 있음을 의미한다. 좌측에서 우측으로 파싱하면 객체가 먼저오고 그것이 수신하는 메시지가 뒤따른다. 다음에 발생하는 일은 정수가 말하기 요청에 응답하도록 프로그래밍되었는지 여부와 어떻게 프로그래밍되었는지에 따라 전적으로 좌우된다. 예를 들어, 필자가 보인 스몰토크 시스템에서 9 talk의 실행 결과는 화면에 다음과 같은 텍스트가 뜨는 것이다: Hello, I am one more than 8. 동일한 구문으로 된 또 다른 예제는 다음과 같다:

4 factorial


좌측에서 우측까지 필자는 4 object가 4의 계승, 즉 4*3*2*1을 계산하도록 요청하고 있다. 스몰토크에게 결과를 표시하도록 요청할 경우 24 를 얻을 것이다. (실행과 표시의 차이는 다음 절에서 논하겠다.) 이 예제는 앞 절의 논의와 비슷해야 한다:

6 * 7


좌측부터 우측으로 6은 메시지 *7을 수신한다. 필자가 스몰토크에게 결과를 표시하라고 요청할 경우 우리는 보게 될 값은 42이다. '좌측에서 우측으로' 규칙은 놀라운 일을 야기할 수 있다; 스몰토크 초보자들 중 절반은 아래와 같은 질문에 틀린 응답을 예상한다:

5 + 6 * 2


올바른 답은 17이 아니라 22이다. 왜일까? 좌측에서 우측으로 진행하라. 5 object는 + 연산의 요청, 즉 +6 메시지를 수신한다. 그 결과인 11 object는 그 순서대로 (좌측에서 우측으로) * 연산에 대한 요청, 즉 *2 메시지를 수신한다. 그리고 11 object는 최종 결과인 22 object로 응답한다. 학교에서 배운 것과 분명하게 다른 스몰토크 예제는 처음일 것이다. 좋든 싫든 스몰토크는 이렇게 작동한다. 정말로 17을 답으로 얻고 싶다면 스몰토크의 파스(parse)의 우선권을 변경하기 위해 괄호를 사용할 수도 있다:

5 + (6 * 2)


다음 예제는 약간의 짐작이 필요하다:
'turnip' reversed


좌측에서 우측으로 진행하면, 첫 번째 요소인 'turnip' 은 메시지를 수신하는 객체이다. 단일 인용 표시가 사용되었으므로 그 내용을 문자열로 추측하는 것이 합당하겠다. 보아하니 메시지는 문자열을 뒤집도록 요청하고 있다. 스몰토크에게 결과를 표시하도록 요청할 경우, 스몰토크는 나열된 원본 문자열의 문자를 거꾸로 표시할 것이다: 'pinrut'.

이번 내용은 또 다른 형태를 가진다:
HomeBudget spend: 229 on: 'VCR'


좌측의 객체는 가계부(home accounting)와 재고 목록(inventory)을 관리하는 것으로 보인다. 그리고 메시지가 덜 분명하다. 콜론은 argument의 존재를 신호로 보낸다는 사실이 기억날 것이다. 그렇지만 콜론이 두 개라면 어떨까? 이러한 상황에 대한 스몰토크의 파싱 규칙은 모든 콜론과 그것의 argument를 모두 단일 메시지로 취급하자는 것이다. 따라서 spend: 229 on: 'VCR' HomeBudget 을 겨냥한 하나의 전보에 포장된 복잡한 정보 꾸러미이다. 전보(메시지)가 객체에게 '$220을 지불하여 새로운 VCR을 구매한다'는 사실을 통지하는 것은 분명하다. 필자의 시스템에서 스몰토크에게 이 표현식을 실행하도록 요청할 경우 스몰토크는 다음과 같이 응답한다: You bought a VCR and you are poorer by 229 dollars. (당신은 VCR을 구매하였으며 229 달러만큼 줄었습니다.)


Pitfall: 효과 대 리턴

연산이 하는 일과-연산의 효과-그것이 호출자에게 리턴하도록 선택하는 객체 간에 차이점을 주목하라. 상황에 따라 둘 중 하나를 더 신경 써야 할지 모른다. 때때로 연산의 이름을 통해 효과의 중요성이 제시되기도 한다:

7 storeOn: someFile


이러한 표현식은 7 객체를 someFile 인자가 참조하는 파일 내 디스크 위로 위치시키는 효과가 있는 것처럼 보인다. 누가 봐도 이 효과가 메시지의 목적이다; 따라서 객체가 전송자(sender)에게 무엇을 리턴하는지는 무관하다. 때로는 앞 절의 9 talk 예제에서와 같이 화면으로 피드백을 명시적으로 표시하는 것이 효과의 일부가 되기도 한다. 9 talk 객체가 무엇을 리턴하는지는 신경 쓰지 않는다; 그 객체가 무엇인지는 상관이 없다.

이와 반대의 경우가 사실이 될 수도 있다.

7 factorial


위에서 우리는 factorial 가 계산을 실행하는 동안 발생하는 효과는 신경 쓰지 않는다. 우리는 계산이 완료되었을 때 돌아오는 객체, 즉 5040에 훨씬 더 관심이 있다. 이런 경우 효과가 아니라 리턴값을 보고 싶은 것이다.

당신은 스몰토크가 리턴값을 표시할 것인지 말 것인지를 명시할 수 있다. 이것이 바로 앞 절에 설명한 표시하기와 실행하기의 세심한 차이이다. 표현식을 표시할 경우 효과가 발생하고, 스몰토크는 리턴된 객체를 화면에 표시한다. 표현식을 실행하기만 원할 경우 효과는 발생하지만 스몰토크는 리턴된 객체를 무시한다. 당신은 여태까지 소개한 예제들에서 표시하기 또는 실행하기 연산을 구현하는 코드를 보지 못했으므로 그에 관한 필자의 선택을 신뢰해야만 한다. 연산의 이름을 통해 연산의 효과와 리턴값을 제안할지는 모르지만, 코드를 읽는 편이 확실하기 때문이다. 제 4장에서는 그 차이를 분명하게 확인하도록 도와줄 연습문제를 살펴볼 것이다.


객체가 중요한 이유

모든 수사법을 제쳐두면-재사용 가능성과 생산성 등에 관한 수사법-객체의 핵심적인 특성은 해석을 감소시킨다는 점이다. 즉, 객체는 공통 어휘의 사용을 촉진한다: 소프트웨어 전문가든 아니든 모든 사람은 객체가 무엇인지에 대해 어느 정도 직관적으로 이해한다. 따라서 우리는 객체를 이용해 생각을 설명하여 좀 더 쉽게 서로를 이해할 수 있는 것이다. 객체는 사용자, 분석자, 운영자, 설계자, 프로그래머, 검사자(tester)들 간 상호 이해를 고취시킨다. 객체는 어떤 사람의 사고를 타인의 사고로 번역하는 수고를 덜어주므로 한 사람으로부터 다른 사람으로 전달될 때 오해를 줄인다.

재사용과 생산성에 대해 말하자면, 이는 더 나은 이해의 부가적 영향에 불과하다. 부가적 영향보다는 분명한(clear) 객체에 중점을 두는 것이 더 중요하다; 객체를 분명하게 이해하지 않으면 생산적이지 못할 뿐 아니라 재사용도 불가하다. 분명한 객체에 중점을 두면 결국 재사용 가능한 객체를 생산하게 될 것이다; 재사용 가능한 객체에 중점을 두면 혼란스러운 객체를 생산할 것이다. 이러한 점에서 미루어 볼 때 본 저서는 당신이 객체를 명확하고 깊이 이해하여 최종적으로는 소프트웨어 사업에서 다른 사람들을 이해하고 다른 사람들에 의해 이해되는 능력을 강화시키는 것을 목표로 한다. 그리고 그것이야말로 객체의 경제적 가치의 근원인 셈이다.


개요: 객체

프로그래밍 객체는 사람마다 다른 이유를 호소한다. 우뇌(right brain)에 해당하는 직관적인 사람들은 그들의 은유적 힘을 인식한다. 예를 들어, Brooklyn Union Gas Company1의 객체 지향 고객 정보 시스템은 회사의 실제 문제가 되는 영역의 가스 계량기(gas meters) 및 요금(bills)과 정확히 동일한 gas meter 및 bill 객체들을 갖고 있다. 가스 계량기 소프트웨어를 개발하기 위해 개발자들은 실제 가스 계량기를 상상한다. 이러한 방식은 객체들을 그들의 일상 경험에 이미 익숙한 방식으로 프로그래밍하는데 대한 추론을 돕는다; 그것은 문제와 (가스 서비스의 요금) 해결책 (프로그래밍) 간 격차를 줄여준다. 이러한 인지 경제성(cognitive economy)이-두 영역 간 격차를 없애는-은유법의 본질이다.

반면 좌뇌, 분석적인 사람들은 객체의 소프트웨어 공학적 이익에 매료된다. 소프트웨어가 그 정의에 의해 캡슐화된 객체로 구성된다면, 외부에 영향을 미치지 않고, 그에 따라 나머지 시스템 부분에 영향을 미치지 않고 내부를 향상시킬 수 있다. 문제들은 특정 객체로 쉽게 분리되고 고정되며, 시스템은 주로 변화에 더 관용적이고 가변적(malleable)이다. 짧게 말해, 소프트웨어에서 모듈성(modularity)이 바람직하고, 객체들은 전형적인 구성(structuring)기법을 능가하는 모듈성 수준을 제공한다.

객체에서 또 한 가지 언급할 가치가 있는 내재적 특성이 있다. 전형적인 소프트웨어 구성 기법들은 먼저 함수-프로그램의 function, 그것의 sub-function, 그것의 sub-sub-function 등등-에 중점을 둔다. 하지만 인간의 인지는 사물을 먼저 인식하고 사물들을 연결하는 함수는 후에 인식하는 방식으로 작동한다. 예를 들어, 이웃집 개가 우체부를 물어 뜯는 소리를 듣게 되면 필자는 두 적수의 그림이 먼저 떠오르고, 조금 시간이 지나면 피해자의 다리에 닿을랑 말랑한 개의 이빨이 생각난다. 추상적인 물기(bite)가 먼저 떠오르지 않는다는 말이다. 우리 마음은 자연적으로 일상세계에서 사물을 사고하도록 연습해왔는데 그 연습을 소프트웨어 세계에서 활용하지 말아야 할 이유가 무엇이 있겠는가? 이것은 객체가 우리 프로그래머들을 위해 하는 일이다.

객체

지금까지 이용할 수 있는 조직을 요약하자면 다음과 같다: 프로그래밍 객체가 있다면 필자는 우측 도표와 같이 객체들로부터 소프트웨어를 빌드할 수 있다. 불행하게도 이 소프트웨어에는 구조가 많지 않다-서로 통신하는 혼돈 상태의 객체에 불과하다. 다음 장에서는 구조 원칙들을 통해-클래스와 상속-그림을 채워 넣을 것이다.


연습: 준비 단계 (image)

일반적으로 image는 당신이 사용하고 생성하는 모든 객체를 비롯해 다른 중요한 스몰토크 객체들을 포함하는 파일이다. 스몰토크를 시작하면 이미지가 활성화되고 수만 개에서 수십 만개에 달하는 모든 객체들이 활발해지면서 요청을 받으면 작동할 준비를 한다. IBM 스몰토크에서 이미지 파일에 대한 기본명은 간단히 image다.

❏ 스몰토크를 일단 설치하고 나면 재해 복구에 대한 규정을 어느 정도 만들어라. 최소 규정은 당신이 선택한 백업 파일에 이미지 파일을 복사하는 것이다.


❏ 스몰토크 또는 VisualAge의 아이콘을 더블 클릭하여 스몰토크를 시작하라. Cut-and-paste 에디터를 사용한 적이 없다면 스몰토크에서 몇 분간 연습하라. System Transcript 창에서 텍스트 행을 입력하고 아래를 어떻게 실행하는지 알아내라:

  • 텍스트 행을 나누고 다시 붙이기. (힌트: <enter> 키와 <backspace> 키를 시도해보라.)
  • 텍스트 행의 일부를 동일한 창의 다른 장소로 복사하기.
  • 일부를 이동하고 삭제하기.


❏ 글(transcript)에 아래를 입력한 다음 한 번에 하나씩 강조한 후 결과 객체를 표시하라:

4 factorial
6 * 7
5 + 6 * 2
5 + (6 * 2)
'turnip' reverse


이제 이미지에서 객체로 작업하고 있다.


논평: 객체에 대한 관점

프로그래밍 객체(페이지 2)의 은유적 특징은 최소한 1970년대 초 Xerox PARC에서 (Palo Alto Research Center) 이루어진 Alan Kay의 선구적인 작업으로 거슬러 올라간다. 모든 사람이 프로그래밍에서 은유가 중요하다는 의견에 동의하는 것은 아니다. 구조화 프로그래밍의 아버지 격인 (혹은 최소한 GOTO 문의 실행자) 저명한 컴퓨터 과학자 Edsger Dijkstra는 1989년 논문에서 비유법과 은유법의 사용을 조롱하면서 대신 전적으로 형식적인 사고(formal thinking)만 지지했다. 그의 논문이 발표된 후 열정적인 답변들이 줄을 이뤄 발표되었다 [Dijkstra et al., 1989]. 발명과 창의성에 관한 연구에서는 형식 추론(formal reasoning)이 아닌 형상화가 창의적인 과정을 촉진시킨다고 제시한다. 수학자 Jacques Hadamard가 실행한 연구에는 이 관점을 명확하게 주장하는 알버트 아인슈타인의 반응도 포함되어 있다 [Hadamard 1954].

적절한 은유법을 발견했다면 어찌되었든 상상력을 제한하지 않도록 주의해야만 한다: 물론 스프레드시트는 어느 회계사의 장부 시트를 영감으로 했지만 실제 장부 시트의 성능을 능가했다. Alan Kay는 이 단계를 은유법을 넘어서는 "마법"이라고 부른다 [Kay 1990]. 사용자 인터페이스에서 은유법과 마법의 사용은 제 13장을 참고한다.

객체의 보완적 특성이자 심지어 의인화 관점의 결과로 볼 수 있는 특성은 바로 그들의 자율성이다 [de Champeaux et al., 1993; Collins 1995]. 자율성은, 객체들이 독립적으로 행동할 가능성이 크다는 사실을 암시하고, 그에 따라 동시에 행동할 수도 있음을 암시한다. 동시에 객체를 실행하는 것은, 십억 개 단위가 함께 행동하는 세포에 대해 생물학적 은유법을 이용한 자연적인 결과이기도 하다 [Kay 1988]. 일부 언어들은 병행성(concurrency)과 객체들을 혼합하지만 두 가지에 모두 적절한 모델은 없다. 실제로 우리는 주로 비객체(non-object) 시스템이ㅡ수기신호 또는 다른 저수준 운영체제 서비스ㅡ사용하는 것과 동일한 기능들 위에 병행 객체(concurrent objects)를 빌드한다. 문제에 대한 연구 접근법들의 샘플링은 [Yonezawa and Tokoro 1987; Agha et al., 1989; Agha et al., 1991; Briot 1992; CACM 1993]를 참고한다.

한 쪽엔 기능을 두고 다른 한 쪽엔 데이터를 두고 대비하면 소프트웨어 디자인에 대한 두 가지 양극적 접근법, 즉 전형적인 기능적 분해와 (1970년대부터 시작) 데이터 위주 또는 엔티티 관계 분해(1970년대부터 시작)로 이어진다. 객체들은 중간 위치를 차지한다; 객체에는 유형성이 있고 엔티티의 데이터 내용을 갖고 있지만 그 외부는 그들의 행위나 기능에 따라 정의된다. 이러한 데이터와 기능의 통합(synthesis)이 바로 객체 위주의 접근법을 다른 접근법들로부터 차별화해준다.


Notes