3. 타입과 추상화
일단 컴퓨터를 조작하는 것이 추상화를 구축하고, 조작하고, 추론하는 것에 관한 모든 것이라는 것을 깨닫고 나면 훌륭한 컴퓨터 프로그램을 작성하기 위한 중요한 전제 조건은 추상화를 정확하게 다루는 능력입니다.
- 현대적인 지하철 노선도가 그 대표적인 추상화의 대표적인 예시이며 정확성을 버리고 목적에 집중한 결과입니다.
#
3.1 추상화를 통한 복잡성 극복- 현실에 존재하는 다양한 현상 및 사물과 상호작용하기 위해서는 우선 현실을 이해해야합니다.
- 사람들은 본능적으로 이해하기 쉽고 예측 가능한 수준으로 현실을 분해하고 단순화하는 전략을 만드는것이 중요합니다.
#
추상화어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법입니다.
복잡성을 다루기 위해서는 추상화는 두 차원에서 이뤄집니다.
- 첫 번째 차원은 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만드는 것입니다.
- 두 번째 차원은 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것입니다.
모든 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것입니다.
#
3.2 객체지향과 추상화#
모두 트럼프일 뿐- 앨리스에는 클로버 병사들이나 하트 왕, 하트 여왕이 등장하는데 이를 하나의 트럼프로 볼 수 있습니다.
- 이는 차이점을 무시하고 공통점만 취해 단순화한 결과입니다.
#
그룹으로 나누어 단순화하기- 앨리스에 등장하는 여러 등장인물이 있지만, 사람 수로 나누는 것이 아닌 일반적으로 트럼프의 그룹이나, 토끼의 그룹과 같이 나눌 수 있습니다.
- 이러한 공통 개념을 통해서 내재된 복잡성을 줄일 수 있습니다.
#
개념- 공통적인 특성을 기준으로 객체를 여러 그룹으로 묶어 동시에 다뤄야하는 가짓 수를 줄임으로써 상황을 단순화하려고 노력합니다.
- 공통점을 기반으로 객체들을 묶기 위한 그릇을 개념(concept) 이라고 합니다.
- 개념을 이용하면 객체를 여러 그룹으로 분류(classification) 할 수 있습니다.
- 객체에 어떤 개념을 적용할 때, 그 객체를 인스턴스(instance) 라고 합니다.
#
개념의 세 가지 관점일반적으로 객체의 분류장치로 개념을 이야기할 때는 아래의 세가지 관점을 언급합니다.
- 심볼(symbol) : 개념을 가리키는 간략한 이름이나 명칭
- ex) 트럼프
- 내연(intension) : 개념의 완전한 정의를 나타내며 내연의 의미를 이용해 객체가 개념에 속하는지 여부를 확인합니다.
- ex) 몸이 납작하고 두손과 두발은 네모 귀퉁이에 달려 있는 등장인물, 네모 모양
- 외연(extension) : 개념에 속하는 모든 객체의 집합(set)
- ex) 클로버 병사, 하트 킹, 하트 퀸 등
객체지향에서는 분류(classification) 가 매우 중요하기 때문에 클래스가 유명해졌습니다.
#
객체를 분류하기 위한 틀분류란 객체에 특정한 개념을 적용하는 작업입니다. 객체에 특정한 개념을 적용하기로 결심했을 때 우리는 그 객체를 특정한 집합의 멤버로 분류하고 있는 것입니다.
분류는 객체지향의 가장 중요한 개념 중 하나이고 객체지향의 품질을 결정합니다. 좋은 분류는 애플리케이션의 유지보수를 높이고 변경에 유연하게 대처할 수 있게 해줍니다.
#
분류는 추상화를 위한 도구- 개념은 객체들의 복잡성을 극복하기 위한 추상화 도구입니다.
- 추상화를 사용함으로 복잡한 세상을 제어 가능한 수준으로 단순화합니다.
#
3.3 타입#
타입은 개념이다타입은 개념과 동일합니다. 따라서 타입이란 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 의미합니다. 어떤 객체에 타입을 적용할 수 있을 때 그 객체를 타입의 인스턴스라고 합니다. 타입의 인스턴스는 타입을 구성하는 외연인 객체 집합의 일원이 됩니다.
#
데이터 타입타입에 대한 여러 개념이 있지만, 아래의 두가지 중요한 사실을 알 수 있습니다.
- 첫째, 타입은 데이터가 어떻게 사용되느냐에 관한 것입니다.
- 둘째, 타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 철저하게 감춰집니다.
데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는 데 사용하는 메모리 집합에 관한 메타데이터입니다. 데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정합니다.
#
객체와 타입객체의 타입을 이야기할 때는 아래 두가지 조건을 고려합니다.
- 첫째, 어떤 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동입니다.
- 둘째, 객체의 내부적인 표현은 외부로부터 철저하게 감춰집니다. 객체의 행동을 가장 효과적으로 수행할 수 있다면 객체 내부의 상태를 어떤 방식으로 표현하더라도 무방합니다.
위의 내용을 요약하면, 동일한 책임을 수행하는 일련의 객체는 동일한 타입에 속합니다.
#
행동이 우선이다아래에서는 객체 지향에서 자주 등장하는 대표적인 개념입니다.
- 다형성 : 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 의미합니다.
- 캡슐화 : 객체 지향 설계에서 외부에 행동만을 제공하고, 데이터를 행동 뒤로 감추는 원칙
- 책임-주도 설계(Responsibility-Driven Design)
- 객체가 외부에 제공해야 하는 책임을 먼저 결정하고 그 책임을 수행하는데 적합한 데이터를 결정하고, 이를 표현할 데이터를 나중에 결정합니다.
- 이는 데이터-주도 설계(Data-Driven Design) 방법의 단점을 개선하기 위해 고안됬습니다.
결론적으로 객체를 결정하는 것은 행동입니다. 데이터는 단지 행동을 따릅니다. 이 것이 객체를 객체답게 만드는 가장 핵심적인 원칙입니다.
#
3.4 타입의 계층#
트럼프 계층앞서 나온 트럼프는 트럼프 인간입니다. 즉, 트럼프 인간은 트럼프의 역할(하트 9, 하트 퀸)을 수행하지만 반대는 성립하지 않습니다. 이러한 두 관계를 일반화/특수화(generalization/specialization) 라고 합니다.
#
일반화/특수화 관계일반화와 특수화는 동시에 일어납니다. 이 차이를 인지하는 것도 중요하지만 이 관계를 결정짓는 것은 행동입니다.
- 일반적인 타입은 특수한 타입에 비해 더 적은 수의 행동을 가지며 특수한 타입은 일반적인 타입에 비해 더 많이 행동합니다.
- 특수한 타입은 일반적인 타입이 할 수 있는 모든 행동을 동일하게 수행할 수 있어야합니다.
- 일종의 인터페이스라고 생각하면 편합니다.
#
슈퍼타입과 서브타입- 일반적인 타입을 슈퍼타입(Supertype) 이라고 하고, 좀 더 특수한 타입을 서브타입(Subtype) 이라고 합니다.
#
일반화는 추상화를 위한 도구다- 객체지향 패러다임을 통해 세상을 바라보는 대부분의 경우는 분류와 일반화/특수화 기법을 동시에 적용합니다.
#
3.5 정적 모델#
타입의 목적- 타입을 사용하는 이유는 인간의 인지 능력으로는 시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기가 너무 어렵습니다.
- 타입은 시간에 따라 동적으로 변하는 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해줍니다.
- 결국 타입은 상태에 복잡성을 부과하는 요소를 제거함으로 단순화하고 인지하기 쉬운 형태로 다룰 수 있게합니다.
#
그래서 결국 타입은 추상화다타입은 추상화입니다.
- 타입을 이용하면 객체의 동적인 특성을 추상화할 수 있습니다.
- 타입은 시간에 따른 객체의 상태 변경이라는 복잡성을 단순화할 수 있는 효과적인 방법입니다.
#
동적 모델과 정적 모델- 객체 다이어그램(object diagram) : 객체가 특정 시점에 구체적으로 어떤 상태를 가지는지를 의미, 객체의 스냅샷(snapshot)
- 동적 모델(dynamic model) : 스냅샷처럼 실제로 객체가 살아 움직이는 동안 상태가 어떻게 변하고 행동하는지를 포착합니다.
- 타입 모델(type diagram) : 객체가 가질 수 있는 모든 상태와의 모든 행동을 시간에 독립적으로 표현하는 것
- 정적 모델(static model) : 동적으로 변하는 객체의 상태가 아니라 객체가 속한 타입의 정적인 모습을 표현합니다.
#
클래스- 객체지향 프로그래밍 언어에서 정적인 모델은 클래스를 이용해 구현합니다. (가장 보편적인 방법)
- 클래스와 타입은 비슷하다고 생각할 수 있으나 타입은 객체를 분류하기 위해 사용하는 개념이고 클래스는 단지 타입을 구현할 수 있는 여러 구현 메커니즘 중 하나입니다.
- 객체를 분류하는 기준은 타입이고, 타입을 나누는 기준은 객체가 수행하는 행동입니다.