Smalltalk80LanguageImplementationKor:Chapter 01

From 흡혈양파의 번역工房
Revision as of 09:44, 16 June 2015 by Onionmixer (talk | contribs) (bluebook kor chapter 1 한글번역 추가)
(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)
Jump to navigation Jump to search
1장 객체와 메시지

객체와 메시지

객체는 Smalltalk-80 소프트웨어 시스템의 구성요소를 나타낸다. 가령, 객체는 아래를 표현한다.

  • 숫자
  • 문자열(character string)
  • 큐(queue)
  • 사전
  • 직사각형
  • 파일 디렉터리
  • 텍스트 에디터
  • 프로그램
  • 컴파일러
  • 전산 처리
  • 재정 내역(financial histories)
  • 정보 보기


객체는 몇 가지 private 메모리와 연산 집합으로 구성된다. 객체 연산의 특성은 그것이 표현하는 구성요소 타입에 따라 좌우된다. 숫자를 표현하는 객체들은 산술 연산을 계산한다. 데이터 구조체를 나타내는 객체들은 정보를 보관하고 검색한다. 또 위치와 면적을 나타내는 객체들은 다른 위치와 면적에 관한 질문에 답한다.


메시지는 객체가 자신의 연산 중 하나를 실행하도록 하는 요청이다. 메시지는 어떤 연산이 바람직한지를 명시할 뿐, 연산이 어떻게 실행되어야 하는지는 명시하지 않는다. 메시지를 수신하는 객체인 수신자(receiver)는 요청 받은 연산을 어떻게 실행할 것인지 결정한다. 가령 덧셈(addition) 연산은 숫자를 표현하는 객체로 메시지를 전송함으로써 실행된다. 메시지는 바람직한 연산이 덧셈임을 명시하고, 수신자에게 어떤 숫자가 추가되어야 하는지도 명시한다. 메시지는 덧셈이 어떻게 실행될 것인지는 명시하지 않는다. 덧셈을 어떻게 실현할 것인지는 수신자가 선택한다. 컴퓨팅은 메시지를 전송함으로써 균일하게 호출될 수 있는 객체의 내재적 기능으로 볼 수 있겠다.


객체가 응답할 수 있는 메시지 집합을 시스템 나머지 부분과의 인터페이스라고 부른다. 객체와 상호작용할 수 있는 유일한 방법은 그 인스턴스를 통해서다. 객체의 중요한 특성으로, 객체 고유의 연산에 의해서만 private 메모리를 조작할 수 있다는 점을 들 수 있다. 메시지의 중요한 특성은, 메시지가 객체의 연산을 호출하는 유일한 방법에 해당한다는 것이다. 이러한 특성들은 한 객체의 구현이 다른 객체의 내부적 세부사항에 의존할 수 없고, 그들이 응답하는 메시지에만 의존하도록 보장한다.


메시지는 바람직한 연산 타입을 명시하지만 연산이 어떻게 실현되어야 하는지는 명시하지 않기 때문에 시스템의 모듈화를 보장한다. 예를 들어, Smalltalk-80 시스템에는 몇 가지 수치 값 표현들이 있다. 분수, 작은 정수(small integer), 큰 정수(large integer), 부동 소수점 수는 서로 다르게 표현된다. 이 값들은 모두 동일한 메시지를 이해하면서 다른 숫자와의 총계 계산을 요청하지만 각 표현은 총계를 계산하는 다른 방식을 암시한다. 숫자 또는 다른 객체와 상호작용하기 위해서는 객체가 어떤 메시지에 응답하는지만 알아도 충분하며, 그것이 어떻게 표현되는지는 몰라도 된다.


다른 프로그래밍 환경들도 객체와 메시지를 사용해 모듈러 디자인을 가능하게 한다. 예를 들어, Simula는 이들을 이용해 시뮬레이션을 설명하고, Hydra는 분산 시스템에서 운영체제 기능을 설명하기 위해 사용한다. Smalltalk-80 시스템에서 객체와 메시지는 전체적인 프로그래밍 환경을 구현하는 데에 사용된다. 객체와 메시지가 이해되고 나면 전체 시스템이 접근 가능해진다.


프로그래밍에서 흔히 사용되는 데이터 구조체의 예로 사전을 들 수 있는데, 이는 이름과 값을 연관시킨다. Smalltalk-80 시스템에서 사전은 두 개의 연산, 즉 이름을 새로운 값과 연관시키는 연산과 특정 이름과 마지막으로 연관된 값을 찾아내는 연산을 수행할 수 있는 객체로 표현된다. 사전을 사용하는 프로그래머는 이 두 연산을 메시지로 명시하는 방법을 알아야만 한다. Dictionary 객체는 "Brett이란 이름과 값 3을 연관시켜라" 또는 "Dave란 이름과 연관된 값은 무엇인가?" 식의 요청을 하는 메시지를 이해한다. 모든 것은 객체이기 때문에 Brett이나 Dave와 같은 이름과 3이나 30과 같은 값 또한 객체로 표현된다. 호기심이 많은 프로그래머라면 사전에서 연관(association)이 어떻게 표현되는지 궁금하겠지만 이러한 내부적 구현 정보는 사전을 성공적으로 사용하는 데에 불필요하다. 사전의 구현에 대한 지식은 dictionary 객체 자체의 정의를 작업하는 프로그래머에게만 관심의 대상이 된다.


Smalltalk-80 프로그램을 디자인하는 데에 있어 중요한 부분은 어떤 유형의 객체가 설명되어야 하며, 어떤 메시지명이 이러한 객체들 간 상호작용에 대해 유용한 어휘를 제공하는지 결정하는 것이다. 언어는 객체로 전송 가능한 메시지를 프로그래머가 명시할 때마다 디자인된다. 객체의 적절한 선택은 물론 객체의 목적과 조작되어야 하는 정보의 입도(granularity)에 따라 좌우된다. 예를 들어, 다양한 놀이기구에서 대기줄에 관한 데이터를 수집하려는 목적으로 놀이공원의 시뮬레이션을 생성한다면 놀이기구, 놀이기구를 제어하는 직원, 대기줄, 공원을 방문하는 사람을 표현하는 객체를 설명하면 유용할 것이다. 공원에서 음식의 소비 감시가 시뮬레이션의 목적에 포함된다면 놀이기구 비용에 관한 세부내용도 나타내야 할 것이다.


Smalltalk-80 애플리케이션을 디자인하는 동안 객체의 선택은 첫 번째 주요 단계가 된다. 사실상 객체를 선택하는 "올바른 방법"을 이야기 할만큼 확정적인 것은 없다. 여느 디자인 과정과 마찬가지로 이는 습득하는 기술에 해당한다. 여러 다른 선택들은 애플리케이션을 확장하거나 다른 용도로 객체를 사용하기 위한 여러 기반을 제공한다. 숙련된 Smalltalk-80 프로그래머는 객체에 대해 구문적으로 완전한 함수 집합이 명시되어 있다면 애플리케이션에 대해 생성된 객체가 오히려 다른 애플리케이션에 더 유용하다는 사실을 명심한다. 예를 들어, 연관의 추가 뿐 아니라 제거가 가능한 사전은 주로 추가만 가능한 버전보다 유용하다.


클래스와 인스턴스

클래스는 모두 동일한 유형의 시스템 구성요소를 나타내는 객체 집합의 구현을 설명한다. 클래스가 설명하는 각각의 객체들을 객체의 인스턴스라고 부른다. 클래스는 그 인스턴스의 private 메모리 형태를 설명하고, 객체가 어떻게 연산을 실행해야 하는지를 설명한다. 예를 들어, 직사각형 영역을 표현하는 객체의 구현을 설명하는 시스템 클래스가 있다. 이 클래스는 각 인스턴스들이 그들의 면적 위치를 어떻게 기억하는지, 직사각형 영역이 실행하는 연산을 인스턴스가 어떻게 실행하는지 설명한다. Smalltalk-80 시스템 내 모든 객체는 클래스의 인스턴스에 해당한다. 유일한 시스템 구성요소를 나타내는 객체조차 클래스의 단일 인스턴스로 구현된다. Smalltalk-80 시스템에서 프로그래밍은 클래스를 생성하고, 클래스의 인스턴스를 생성하며, 이러한 객체들 간 메시지 교환 순서를 명시하는 것으로 구성된다.


클래스의 인스턴스는 public 프로퍼티와 private 프로퍼티에서 비슷하다. 객체의 public 프로퍼티는 그 인터페이스를 구성하는 메시지들이다. 클래스의 모든 인스턴스는 동일한 유형의 구성요소를 표현하기 때문에 동일한 메시지 인터페이스를 갖는다. 객체의 private 프로퍼티는 private 메모리를 구성하는 인스턴스 변수의 집합과, 객체의 연산을 어떻게 실행하는지 설명하는 메서드 집합이 해당된다. 인스턴스 변수와 메서드는 다른 객체에서는 직접 이용할 수 없다. 클래스의 인스턴스들은 모두 동일한 메서드 집합을 이용하여 연산을 설명한다. 예를 들어, 직사각형 도형을 나타내는 인스턴스들은 모두 동일한 메시지 집합에 응답하며, 응답 방식을 결정하는 데에 모두 똑같은 메서드를 사용한다. 각 인스턴스에는 고유의 인스턴스 변수 집합이 있지만 인스턴스 변수의 개수는 주로 같다. 예를 들어, 직사각형을 나타내는 인스턴스들은 모두 두 개의 인스턴스 변수를 가진다.


각 클래스에는 그것의 인스턴스가 나타내는 구성요소 타입을 설명하는 이름이 붙여진다. 클래스명은 특수 글꼴로 표시되는데, 프로그래밍 언어의 일부이기 때문이다. Smalltalk-80 표현식을 나타내는 텍스트에는 모두 동일한 글꼴이 사용될 것이다. 인스턴스가 문자 시퀀스를 표현하는 클래스를 String이라고 부른다. 인스턴스가 공간적 위치를 나타내는 클래스는 Point로 불린다. 직사각형 영역을 나타내는 클래스는 Rectangle이라 부른다. 인스턴스가 전산 처리를 나타내는 클래스는 Process라고 부른다.


객체의 private 메모리 내 각 인스턴스 변수는 값이라고 불리는 하나의 객체를 참조한다. Rectangle의 두 인스턴스 변수 값은 직사각형 영역의 반대편 모서리들을 가리키는 Point의 인스턴스들이다. Rectangles에 두 개의 인스턴스 변수가 있다거나, 인스턴스 변수가 Points를 참조한다는 사실은 각 Rectangle 밖에서는 이용할 수 없는, 철저히 내적인 정보에 해당한다.


클래스 내 각 메서드는 특정 타입의 메시지가 요청한 연산을 어떻게 실행하는지 알려준다. 해당 타입의 메시지가 클래스의 어떤 인스턴스로든 전송되면 메서드가 실행된다. 모든 Rectangles가 사용하는 메서드는 반대쪽 모서리를 나타내는 두 개의 Points와 관련해 그 연산을 어떻게 실행할 것인지 설명한다. 예를 들어, 한 메시지가 Rectangle에게 중심 위치를 묻는다. 그에 상응하는 메서드는 반대편 모서리 중간에 있는 점을 찾아 중심을 계산하는 방법을 알려준다.


클래스는 그 인스턴스가 실행할 수 있는 연산 타입마다 메서드를 포함한다. 메서드는 객체의 private 메모리, 그리고 전송되어야 할 다른 메시지들에 대한 변경내용을 명시한다. 메서드는 그 외에도 호출하는 메시지의 값으로 리턴되어야 하는 객체를 명시하기도 한다. 객체의 메서드는 객체 고유의 인스턴스 변수로 접근할 수 있지만 다른 객체의 인스턴스 변수로는 접근할 수 없다. 예를 들어, Rectangle이 그 중심을 계산하기 위해 사용하는 메서드는 그 인스턴스 변수가 참조하는 두 개의 Point로 접근성을 갖지만, 그러한 Points의 인스턴스 변수로는 접근할 수 없다. 메서드는 Points에게 필요한 계산의 실행을 요청하는 메시지를 명시한다.


Smalltalk-80에서 작은 메서드 하위집합은 Smalltalk-80 프로그래밍 언어에 표시되지 않는다. 이들은 프리미티브 메서드라고 부른다. 프리미티브 메서드는 가상 머신에 빌드되며, Smalltalk-80 프로그래머가 변경할 수 없다. 이들은 다른 메서드와 정확히 같은 방식으로 메서드를 이용해 호출된다. 프리미티브 메서드는 기본이 되는 하드웨어와 가상 머신 구조체로의 접근을 허용한다. 예를 들어, Integer의 인스턴스들은 + 메시지에 응답하기 위해 프리미티브 메서드를 사용한다. 그 외 프리미티브 메서드는 디스크와 단말기(terminal) 상호작용을 실행한다.


예제 애플리케이션

예제는 프로그래밍 언어와 환경에 대한 설명에 중요한 부분이다. 본문에 사용된 예제의 대다수는 표준 Smalltalk-80 시스템에서 발견되는 예제들이다. 그 외 예제들은 기능을 향상시키기 위해 시스템에 추가될 수 있는 클래스로부터 취한 것이다. 본 서적의 제 1부는 개인, 가정, 단체 또는 소규모 사업을 대상으로 한 간단한 재정 내역(financial history)을 유지하기 위해 시스템에 추가할 수 있는 애플리케이션에서 예제를 도출하였다. 전체적인 애플리케이션은 입력해야 할 금융 거래와 표시되어야 하는 정보 보기를 허용한다. 그림 1.1은 Smalltalk-80 디스플레이 화면에 표시될 재정 내역의 모습이다. 뷰의 상단에 위치한 두 개의 부분은 다양한 용도로 사용된 자금의 금액을 표시하는 두 개의 뷰다. 그 아래의 뷰는 거래가 이루어질 때 시간의 흐름에 따라 수중의 현금이 어떻게 변하는지 보여준다.


그림 하단에는 사용자가 새로운 지출과 수익을 기록에 추가하기 위해 입력할 수 있는 두 개의 영역이 존재한다. 새로운 정보가 추가되면 세 개의 뷰가 자동으로 업데이트된다. 그림 1.2에서는 식품에 대한 새로운 지출이 추가된 모습이다.


이 애플리케이션은 시스템으로 여러 클래스의 추가를 필요로 한다. 이러한 새 클래스들은 기본이 되는 재정 내역 정보뿐 아니라 여러 가지 유형의 뷰를 설명하기도 한다. 재정 내역을 실제로 기록하는 클래스는 FinancialHistory라고 부르며, 다음 네 개의 장에서 예제로 사용될 것이다. 이러한 애플리케이션 예제는 시스템에 이미 존재하는 몇 가지 클래스를 사용할 것이며, 숫자를 사용해 금액을 표현하고 지출의 이유와 수익의 출처는 문자열을 사용해 표현할 것이다.


FinancialHistory는 기능과 구현을 설명하기 쉬우므로 이를 이용해 Smalltalk-80 프로그래밍 언어의 기본 개념을 소개할 것이다. 클래스의 기능은 메시지 인터페이스를 통해 이용 가능한 연산을 열거함으로써 명시할 수 있다. FinancialHistory는 6개의 연산을 제공한다.

  1. 이용할 수 있는 초기 금액이 확정된 새로운 재정 내역 객체를 생성한다.
  2. 특정 금액이 어떤 용도로 사용되었음을 기억한다.
  3. 특정 금액이 어떤 출처로부터 들어왔음을 기억한다.
  4. 금액을 얼마나 이용할 수 있는지 알아낸다.
  5. 어떤 용도에 얼마나 소비했는지 알아낸다.
  6. 어떤 출처로부터 얼마나 수신하였는지 알아낸다.


그림 1-1

그림 1-2


이러한 연산들의 구현은 본 서적의 표지 커버 안에 표시된 클래스 설명(class description)에 명시되어 있다. 클래스 설명의 구성은 제 3, 4, 5장에서 설명할 것이다.


시스템 클래스

Smalltalk-80 시스템은 프로그래밍 언어와 환경의 표준 기능, 즉 산술, 데이터 구조체, 제어 구조체, 입/출력 기능을 제공하는 클래스 집합을 포함한다. 이러한 클래스들의 기능은 본 서적의 제 2부에서 상세히 설명할 것이다. 그림 1.3은 제 2부에 제시한 시스템 클래스의 다이어그램이다. 관련된 클래스 그룹 주위에 직선을 그렸으며, 그룹은 클래스 명세를 찾을 수 있는 장(chapter)을 나타내도록 라벨로 붙였다.

산술(Arithmetic)

Smalltalk-80 시스템은 실수와 유리수를 모두 표현하는 객체를 포함한다. 실수는 약 6자릿수의 정확도로 표현할 수 있다. 252428s 보다 작은 절대값의 정수는 정확히 표현 가능하다. 유리수는 이러한 정수를 이용해 나타낼 수 있다. 선형적 크기(예: 일자와 시간)와 무작위 수 발생기를 나타내기 위한 클래스들도 있다.


데이터 구조체

Smalltalk-80 시스템 내 대부분의 객체는 어떤 유형의 데이터 구조체로 기능한다. 하지만 대부분의 객체들은 다른 기능도 가진 반면 다소 순수한 데이터 구조체를 표현하는 클래스 집합이 있다. 이러한 클래스들은 여러 타입의 컬렉션을 표현한다. 일부 컬렉션의 요소(element)들은 정렬되지 않고 나머지는 정렬된다. 정렬되지 않은 요소가 있는 컬렉션 중에는 중복 요소를 허용하는 백(bag)과 중복을 허용하지 않는 세트(set)가 있다. 또 객체의 쌍을 연관시키는 사전도 존재한다. 정렬된 요소들 중에서 일부는 요소가 추가될 때 외부적으로 순서가 명시되고, 요소의 프로퍼티를 기반으로 하여 스스로를 정렬하기로 결정하는 요소들도 있다. 문자열과 배열에 공통된 데이터 구조체는 연관 행위(색인과 요소를 연관시킴)와 외부 정렬(색인의 내재적 정렬에 상응)을 가진 클래스에 의해 제공된다.


제어 구조체

Smalltalk-80 시스템은 대부분의 프로그래밍 언어에서 발견되는 표준 제어 구조체를 구현하는 메시지와 객체를 포함한다. 이들은 Algol의 if-then-else문과 비슷한 조건 선택과 while 또는 until 문과 비슷한 조건 반복을 제공한다. 스케줄링과 동기식 상호작용에 대해 독립된 처리 및 메커니즘을 표현하는 객체들 역시 제공된다. 제어 구조체를 지원하도록 두 가지 클래스가 제공된다. Booleans는 두 개의 사실(truth) 값을 나타내고, 블록은 액션의 순서를 나타낸다. Boolean과 블록을 이용해 새로운 유형의 제어 구조체를 생성할 수 있다.

그림 1-3


프로그래밍 환경

Smalltalk-80 시스템에는 프로그래밍 과정에 도움이 되는 클래스가 몇 개 있다. 이들은 메서드의 컴파일된 (머신이 실행할 수 있는) 형태와 소스(인간이 읽을 수 있는) 형태를 표현하는 구분된 클래스들이다. 파서, 컴파일러, 역컴파일러를 나타내는 객체들은 그들을 사용하는 객체와 (클래스의 인스턴스들) 메서드를 연결한다.


클래스와 메서드에 대한 조직화된 구조체를 나타내는 객체는 프로그래머가 시스템을 추적하도록 돕고, 소프트웨어 수정 내역을 표현하는 객체들은 다른 프로그래머들의 노력과 인터페이스를 돕는다. 심지어 메서드의 실행 상태를 객체가 표현하기도 한다. 이러한 객체들을 컨텍스트라고 부르며, 다른 시스템의 활성화 기록 또는 스택 프레임과 비슷하다고 볼 수 있다.


살펴보기와 상호작용하기

Smalltalk-80 시스템은 정보를 살펴보고 편집하는 데에 사용할 수 있는 객체의 클래스를 포함한다. 그래픽한 뷰를 표현하는 데에 도움이 되는 클래스는 점, 선, 직사각형, 원호를 표현한다. Smalltalk-80 시스템은 비트맵 디스플레이를 지향하기 때문에 비트맵 이미지를 표현하고 조작하는 클래스가 존재한다. 문자 글꼴, 텍스트, 커서를 대상으로 한 좀 더 구체적인 비트맵 이미지의 사용을 표현 및 조작하기 위한 클래스도 존재한다.


이러한 그래픽 객체로부터 직사각형 창, 명령 메뉴, 내용 선택을 나타내는 다른 객체들도 만들어진다. 입력 장치에 대한 사용자의 액션을 나타내는 객체와, 이러한 액션이 현재 보고 있는 정보에 어떻게 연관되는지를 나타내는 객체도 있다. 이러한 구성요소로부터 생성된 편집 메커니즘과 특정 보기(viewing)를 표현하는 클래스들은 클래스, 컨텍스트, 그리고 텍스트와 그래픽을 포함하는 문서에 대해 뷰(view)를 제공한다. 클래스의 뷰는 시스템 내 소프트웨어와 상호작용하기 위해 기본적인 메커니즘을 제공한다. Smalltalk-80과 에디터는 별도의 서적에서 소개한다.


통신

Smalltalk-80 시스템은 외부 매체와의 통신을 허용한다. 표준 외부 매체는 디스크 파일 시스템이 해당한다. 객체는 디렉터리뿐만 아니라 개별 파일을 표현한다. 통신 네트워크의 연결을 이용할 수 있다면 객체를 통해서도 접근할 수 있다.


용어 정리

객체(object) 일부 private 메모리와 연산 집합으로 표현되는 Smalltalk-80 시스템의 구성요소.
메시지(message) 객체가 그 연산 중 하나를 실행하라는 요청.
수신자(receiver) 메시지가 전송되는 대상 객체.
인터페이스(interface) 객체가 반응할 수 있는 메시지.
클래스(class) 유사한 객체 그룹에 대한 설명.
인스턴스(instance) 클래스가 설명하는 객체들 중 하나.
인스턴스 변수(instance variable) 객체의 private 메모리의 부분.
메서드(method) 객체의 연산들 중 하나를 어떻게 실행할 것인지에 대한 설명.
프리미티브 메서드(primitive method) Smalltalk-80 가상 머신에서 직접 실행되는 연산.
FinancialHistory 본 서적에서 예제로 사용된 클래스명.
시스템클래스(system classes) Smalltalk-80 시스템에 따라오는 클래스 집합.


Notes