"객체지향의 사실과 오해" 의 3장/4장의 읽고 정리한 글입니다.
3. 타입과 추상화
추상화
추상화란 현실에서 출발하되 불필요한 부분을 도려내가면서 사물의 놀라운 본질을 드러나게 하는 과정이다. 추상화의 목적은 불필요한 부분을 무시함으로써 현실에 존재하는 복잡성을 극복하는 것으로, 훌륭한 추상화는 목적에 부합해야하는 것이다. 추상화의 수준, 이익, 가치는 오로지 목적에 의존적이다.
추상화는 다음과 같이 2가지 차원에서 이루어진다.
- 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만든다.
- 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만든다.
개념
객체들의 공통적인 특성을 기준으로 여러 그룹으로 묶어 다뤄야 하는 가짓수를 줄임으로써 상황을 단순화하는데, 여기서 공통점을 기반으로 묶기 위한 그릇을 개념 (concept) 이라고 한다. 개념을 이용하면 객체를 여러 그룹으로 분류 (classification, class 의 출발점) 할 수 있다. 그리고 객체에 어떤 개념을 적용하는 것이 가능해서 개념 그룹의 일원이 될 때 객체를 그 개념의 인스턴스 (instance) 라고 한다.
개념의 3가지 관점
어떤 객체에 어떤 개념이 적용됐다고 할 때는 그 개념이 부가하는 의미를 만족시킴으로써 다른 객체와 함께 해당 개념의 일원이 됐다는 것을 의미한다.
객체의 분류 장치로서 개념은 아래와 같이 3가지로 구성되어 있다.
- 심볼 (symbol) : 개념을 가리키는 이름
- 내연 (intension) : 개념의 의미로, 개념을 객체가 적용할 수 있는지 여부를 판단하기 위한 조건
- 외연 (extension) : 개념에 속하는 모든 객체 (개념의 인스턴스) 의 집합
외연의 관점에서 어떤 객체에 어떤 개념을 적용할 수 있다는 것은 동일한 개념으로 구성된 객체 집합에 해당 객체를 포함시키는 것으로, 곧 객체들을 개념에 따라 분류하는 것과 동일하다.
개념과 추상화
개념은 객체들의 복잡성을 극복하기 위한 추상화 도구이다. 개념을 통해 객체를 분류하는 과정은 위에서 다룬 추상화의 2가지 차원을 모두 사용한다.
- 객체들을 어떤 개념으로 묶은 것은 개별 객체 간의 공통점을 취하고 차이점을 버린 결과이다.
- 객체들의 공통점 중에서 중요한 특징 외의 사항은 전적으로 무시하여 불필요한 세부 사항을 제거한다.
타입
타입 (type) 은 개념을 대체할 수 있는 수학적 용어로, 타입의 정의는 개념의 정의와 완전히 동일하므로 개념을 대체한다.
데이터 타입
메모리 내의 데이터들은 0 또는 1로 저장되어 있는데, 메모리 조각에 들어 있는 값의 의미는 그 값을 가져다 자신의 용도에 맞게 사용하는 외부의 해석가에 의해 결정된다. 데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는 데 사용하는 메모리 집합에 관한 메타데이터로, 데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정한다.
타입은 다음과 같은 특징을 갖는다.
- 데이터가 어떤 타입에 속하는지를 데이터에 적용할 수 있는 작업이다.
- 타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 철저하게 감춰진다.
객체와 타입
객체를 타입에 따라 분류하고 그 타입에 이름을 붙이는 것은 프로그램에서 사용할 새로운 데이터 타입을 선언하는 것과 같다. 객체의 타입에 대하여, 위의 데이터 타입에 관한 특징이 동일하게 적용된다.
- 어떤 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동이다.
- 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다.
객체의 내부 표현 방식이 다르더라도 어떤 객체들이 동일하게 행동한다면, 그 객체들은 동일한 타입에 속한다. 객체를 다른 객체와 동일한 타입으로 분류하는 기준은 객체가 타입에 속한 다른 객체와 동일한 행동을 하는지이다. 그 객체가 어떤 데이터를 갖고 있는지는 관심사 아니다! 같은 타입에 속한 객체는 행동만 동일하다면 서로 다른 데이터를 가질 수 있다.
동일한 행동이란 동일한 책임을 의미하므로 동일한 책임은 곧 동일한 메시지 수신을 의미한다. 동일한 타입에 속하는 객체는 내부의 데이터 표현 방식이 다르더라도 동일한 메시지를 수신하고 처리할 수 있지만, 내부의 표현 방식이 다르기 떼문에 동일한 메시지를 처리하는 방식은 서로 다를 수 밖에 없다. (다형성, polymorphism) 또한 데이터 내부 표현 방식과 무관하게 행동만이 고려 대상이므로 외부에 데이터를 감춰야한다. (캡슐화, encapsulation)
행동에 따라 객체를 분류하기 위해서 객체가 내부적으로 관리해야 하는 데이터가 아니라 객체가 외부에 제공해야 하는 행동을 먼저 생각해야한다. 즉, 책임을 먼저 결정하고 적합한 데이터를 결정한 후, 데이터를 외부 인터페이스 뒤로 캡슐화해야한다.
일반화/특수화
예시로 등장한 이상한 나라의 앨리스 이야기에서, 앨리스는 정원사, 병사, 신하 등을 트럼프와 몇 가지 특징을 공유하기 때문에 트럼프라고 불렀지만, 더 정확하게 말하면 등장인물들을 트럼프가 아니라 '트럼프 인간'으로 본다. 여기서 '트럼프 인간' 타입의 객체는 트럼프 타입의 객체가 할 수 있는 모든 행동을 할 수 있을 뿐만 아니라 더 특화된 행동을 할 수 있다. 이는 '트럼프 인간' 타입에 속한 객체는 트럼프 타입의 객체에도 함께 속해야 한다는 것을 의미하므로 트럼프 인간 타입에 속한 객체는 트럼프 타입의 객체에도 함께 속해야 한다는 것을 의미한다.
즉, 트럼프는 프럼프 인간을 포괄하는 좀 더 일반적인 개념인 슈퍼타입 (Supertype) 이고, 트럼프 인간은 트럼프보다 좀 더 특화된 행동을 하는 특수한 개념인 서브타입 (Subtype) 이다. 이 두 개념 사이의 관계를 일반화/특수화 (generalization/specialization) 관계라고 하며, 객체지향에서 일반화/특수화 관계를 결정하는 것은 객체의 상태를 표현하는 데이터가 아니라 행동이라는 점이 중요하다.
** 타입의 내연을 의미하는 행동의 가짓수와 외연을 의미하는 집합의 크기는 반대이다.
일반화/특수화와 추상화
일반화/특수화 계층은 객체지향 패러다임에서 추상화의 2번재 차원을 적절하게 활용한다. 앨리스가 정원사, 병사, 신하 등을 트럼프라고 볼 경우, 트럼프의 특성에 집중하기 위해 '트럼프 인간' 의 특수한 능력은 제거한다. 즉, 일반화/특수화는 추상화된 개념 혹은 타입 내의 책임의 포함 여부에 따라 더 일반적인 개념인지, 특수한 개념인지가 나뉘므로 추상화를 기반으로 한 개념이다.
정적 모델
타입은 시간에 따라 동적으로 변하는 객체의 상태를 시간과 무관한 정적인 모습으로 다뤄, 시간에 따라 동적으로 변하는 객체의 복잡성을 줄인다. 즉, 타입은 추상화로, 어떤 시점에 객체에 관해 생각할 때 불필요한 시간이라는 요소와 상태 변화라는 요소를 제거하고 철저하게 정적인 관점에서 객체를 묘사하는 것을 가능하게 해준다. 즉, 상태의 변화에 대한 가능성을 고려할 때, 현재의 상태보다는 상태가 변할 수 있다는 가능성에 집중하여 정적인 관점에서 객체의 동적인 특성을 추상화한다.
동적 모델과 정적 모델
객체를 생각할 때 2가지 모델을 동시에 고려한다.
- 객체가 특정 시점에 구체적으로 어떤 상태를 가지는지 표현
객체의 상태가 어떻게 변하고 어떻게 행동하는지를 포착하는 동적 모델 (dynamic model) - 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현
객체가 속한 타입의 정적 모습을 표현하는 타입 모델/정적 모델 (type model/static model)
객체지향 어플리케이션을 설계하고 구현하기 위해서 객체 관점의 동적 모델과, 객체를 추상화한 타입 관점의 정적 모델을 적절히 혼용해야 한다.
4. 역할, 책임, 협력
객체의 세계에서는 협력이라는 문맥이 객체의 행동 방식을 결정한다. 객체들 간의 요청과 응답 속에서 창발하는 협력에 초점을 맞춰 애플리케이션을 설계해야하며, 협력이 자리를 잡으면 객체의 행동이 드러나고 뒤이어 적절한 객체의 상태가 결정된다.
협력
각 객체는 동일한 목적을 달성하기 위해 협력하며, 협력은 다수의 요청과 응답으로 구성되고 전체적으로 다수의 연쇄적인 요청과 응답의 흐름으로 구성된다. 각 객체가 특정한 요청을 받아 그 요청에 대해 응답할 수 있는 이유는, 적절한 방식으로 응답하는데 필요한 지식과 행동 방식을 가졌으므로 응답에 대한 의무를 지니기 때문이다. 따라서 요청과 응답은 협력에 참여하는 객체가 수행할 의무, 곧 책임을 정의한다.
책임
객체지향에선 어떤 객체가 어떤 요청에 대해 대답해 줄 수 있거나, 적절한 행동을 할 의무가 있는 경우 해당 객체가 책임을 가진다고 말한다. 객체의 책임은 '객체가 무엇을 알고 있는가' (=knowing, 지식) 와 '무엇을 할 수 있는가' (=doing, 행동 방식) 으로 구성된다.
객체의 책임을 말할 때 일반적으로 외부에서 접근 가능한 공용 서비스의 관점에서 이야기하는데, 책임은 객체의 외부에 제공해 줄 수 있는 정보 (=knowing, 지식) 와 외부에 제공해 줄 수 있는 서비스 (=doing, 행동방식) 의 목록이다. 따라서 책임은 객체의 공용 인터페이스 (public interface) 를 구성한다.
책임과 메시지
책임이 협력이라는 문맥 속에서 요청을 수신하는 한 쪽의 객체의 관점에서 무엇을 할 수 있는지 나열하는 것이라면, 메시지는 협력에 참여하는 두 객체 사이의 관계를 강조한 것이다. 책임은 어떤 객체가 다른 객체의 존재 여부와 관계없이 외부에 제공할 수 있는 행위의 일부인 반면, 메시지는 항상 메시지를 전송하는 객체와 메시지를 수신하는 객체가 상호 협력한다. 두 객체가 협력할 수 있는 이유는 전송하는 수신하는 객체가 이해할 수 있는 메시지를 전송할 수 있고, 수신하는 객체는 전송하는 객체가 보내는 메시지에 대해 적절한 책임을 수행할 수 있기 때문이다.
하지만 책임과 메시지의 수준이 같지는 않다. 책임은 객체가 협력에 참여하기 위해 수행해야 하는 행위를 상위 수준에서 개략적으로 서술했으므로, 책임을 결정한 후 실제로 협력을 정제하면서 이를 메시지로 변환할 때는 하나의 책임이 여러 메시지로 분할되는 것이 일반적이다.
객체지향 설계는 협력에 참여하기 위해 어떤 객체가 어떤 책임을 수행해야 하고 어떤 객체로부터 메시지를 수신할 것인지를 결정하는 것으로부터 시작된다!
역할
역할은 어떤 객체가 수행하는 책임의 집합이자, 재사용 가능하고 유연한 객체지향 설계를 낳는 중요한 요소이다. 즉, 협력 안에서 역할은 "이 자리가 해당 역할을 수행할 수 있는 어떤 객체라도 대신할 수 있다." 라고 말하는 것과 같다. 그리고, 역할을 대체하기 위해서는 각 역할이 수신할 수 있는 메시지를 동일한 방식으로 이해해야 한다. 따라서 동일한 역할을 수행할 수 있다는 것은 해당 객체들이 협력 내에서 동일한 책임의 집합을 수행할 수 있다는 것을 의미한다. 즉, 대체 가능성은 행위 호환성을 의미한다.
역할의 가장 큰 가치는 하나의 협력 안에 여러 종류의 객체가 참여할 수 있게 함으로써 협력을 추상화할 수 있다는 것이다!
타입과 역할
객체는 역할이 암시하는 책임보다 더 많은 책임을 가질 수 있다. 따라서 객체의 타입과 역할 사이에는 일반화/특수화 관계가 성립하는 것이 일반적이다. 좀 더 일반적인 개념을 의미하는 역할은 일반화이며, 좀 더 구체적인 개념을 의미하는 객체의 타입은 특수화이다.
객체의 모양을 결정하는 협력
선입견과 오류
- 시스템에 필요한 데이터를 저장히기 위해 객체가 존재한다.
-> 객체는 행위를 수행하며 협력에 참여하기 위해 존재하므로, 실제로 중요한 것은 객체의 행동/책임이다. - 시스템의 정적인 측면, 즉 클래스와 클래스 간의 관계를 표현하는 데 중점을 둔다.
-> 협력에 참여하는 동적인 객체가 협력 안에서 어떤 책임과 역할을 수행할 것인지 결정하는 것에 중점을 둔다.
협력의 설계
- 협력의 설계 = 설계에 참여하는 객체들이 주고받을 요청과 응답의 흐름을 결정
- 결정된 요청과 응답의 흐름은 객체가 협력에 참여하기 위해 수행될 책임이므로 객체에게 책임을 할당
- 행동을 수행하는데 필요한 데이터 결정
- 클래스의 구현 방법 결정
객체지향 시스템에서 가장 중요한 것은 충분히 자율적인 동시에, 충분히 협력적인 객체를 창조하는 것이므로, 객체를 충분히 협력적으로 만든 후에 협력이라는 문맥 안에서 객체를 충분히 자율적으로 만들어야 한다.
'Books' 카테고리의 다른 글
테스트 주도 개발 정리 - (2) (0) | 2022.01.19 |
---|---|
테스트 주도 개발 정리 - (1) (0) | 2022.01.10 |
객체지향의 사실과 오해 정리 - (3) (0) | 2021.12.29 |
객체지향의 사실과 오해 정리 - (1) (0) | 2021.12.28 |
댓글