추상화는 불필요한 부분을 무시함으로써 단순하게 만드는 것이다.
객체지향에서는 객체라는 추상화를 통해 복잡성을 극복한다.
객체들을 분류하는 것 또한 추상화다. 이 때 분류 장치가 되는 것이 개념(컨셉)이다.
타입은 개념이다. 불필요한 요소를 배제하여 정적인 모델을 다룰 수 있게 하는 추상화 도구다.
객체를 분류하는 기준은 타입(즉, 개념)이며, 이 타입을 나누는 기준은 객체의 행동이다.
타입을 구현하는 한 가지 대표적인 방법이 클래스다. (타입 != 클래스)
추상화를 통한 복잡성 극복
우리는 지하철을 편리하게 이용할 수 있다. 바로 단순하고 직관적인 지하철 노선도가 있기 때문이다.
우리는 지하철 노선도를 볼 때 사실적인 지형을 보진 않는다. 출발점과 환승점, 그리고 그 연결을 본다.
해리 벡은 이러한 목적에 집중하여 노선도를 만들었다.
사실적인 지형(정확성)을 버리고 역 간의 직관적인 연결(목적)에 집중한 것이다.
꼭 알아야 하는 사실만 정확하게 표현하고 다른 정보는 무시함으로써 복잡성을 극복할 수 있었다. 이게 바로 추상화다.
훌륭한 추상화는 목적에 부합해야 한다.
( 해리 벡의 추상화의 목적 == 승객들이 지하철을 바라보는 모델 )이 이루어졌기에 훌륭한 추상화가 될 수 있었다.
이렇듯 추상화의 수준, 이익, 가치는 목적에 의존적이다.
추상화의 목적은 불필요한 부분을 무시함으로써 현실에 존재하는 복잡성을 극복하는 것.
객체지향은 객체라는 추상화를 통해 현실의 복잡성을 극복한다.
추상화는 어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해
특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법이다.
추상화는 두 차원에서 이뤄진다.
- 구체적인 사물들 간의 공통점은 취하고 차이점을 버리는 일반화를 통해 단순하게 만드는 것
- 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것
이것이 정확히 어떠한 과정인지는 마지막에 다시 짚어보도록 하자.
이상한 나라의 앨리스
수많은 객체들이 등장한다. 앨리스, 토끼, 정원사, 병사, 왕자, 공주, 왕, 왕비...
앨리스는 이들 중 일부를 하나로 아울러 생각한다. '기껏해야 트럼프에 불과해.'
이는 정원 내 인물들을 계급/나이/성격 등의 차이점은 무시하고 '트럼프'라는 유사성을 기반으로 추상화한 것이다.
정원사, 병사, 왕자, 공주 등은 서로 구별 가능한 객체다.
이 객체들을 '트럼프'로 한꺼번에 지칭할 수 있는 이유는 이 객체들이 '트럼프'의 일반적인 양식을 지니기 때문이다.
이처럼 공통점을 기반으로 객체를 분류하는 것은 추상화이며, 이 때 분류 장치를 개념(컨셉)이라고 한다.
이렇게 분류된 객체는 개념의 인스턴스가 된다.
어떤 객체를 어떤 개념으로 분류할지가 객체지향의 품질을 결정한다.
객체의 분류 장치인 개념에는 세 가지 관점이 포함된다.
심볼: 개념을 가리키는 간략한 이름이나 명칭
내연: 객체가 개념이 속하는지 여부를 확인할 수 있는 개념의 완전한 정의
외연: 개념에 속하는 모든 객체의 집합
여기서,
심볼: 트럼프
내연: 납작 엎드릴 수 있고 뒤집어질 수 있으며 걸을 때마다 몸이 종이처럼 좌우로 펄럭인다.
외연: 정원사, 병사, 신하, 왕자, 공주, 왕, 왕비
가 되는 것이다.
타입은 개념이다
앞에서 객체들을 분류하는 장치가 개념이라고 했다.
타입도 공통점을 기반으로 객체들을 묶기 위한 틀이다. 동일하다.
앞에서 분류된 객체는 개념의 인스턴스가 된다고 했다.
어떤 객체에 타입을 적용할 수 있을 때 그 객체를 타입의 인스턴스라고 한다. 동일하다.
데이터 타입은 데이터를 분류하기 위해 사용했던 타입니다.
1과 0으로 이루어진 데이터를 분류하기 위함이었다.
데이터 타입에 대한 두 가지 사실을 알아보자.
- 타입은 데이터가 어떻게 사용되느냐에 관한 것이다.
타입을 결정하는 것은 연산자의 종류가 아닌, 어떤 연산자를 적용할 수 있느냐는 것이다.
숫자형은 산술 연산자를 적용할 수 있는 데이터인 것이다. - 타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 철저하게 감춰진다.
우리는 숫자형 데이터 타입의 정확한 표현 방식을 몰라도 데이터를 사용할 수 있다.
당연한 사실이다.
이는 객체 타입에도 동일하게 적용된다.
- 어떤 객체가 어떤 타입에 속하는지 결정하는 것은 객체가 수행하는 행동이다.
- 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다. (캡슐화)
객체의 내부 표현 방식이 다르더라도 동일하게 행동하면 동일한 타입이다.
동일한 행동 == 동일한 책임 == 동일한 메시지 수신
여기서 메시지 처리 방식은 다를 수 있다. 이것이 다형성, 즉 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력이다.
따라서 객체의 내부적인 데이터가 아닌, 외부적인 행동을 먼저 생각해야 한다.
데이터 주도 설계가 아닌, 책임 주도 설계를 지향해야 한다.
책임을 결정한 후, 그 책임을 수행하는 데 적합한 데이터를 결정해야 한다.
그리고 데이터를 외부 인터페이스 뒤로 캡슐화해야 한다.
트럼프라는 타입에서 중요한 것은 종이처럼 납작 엎드릴 수 있는 행동을 하는 것이지, 두 팔다리가 아니다.
객체를 결정하는 것은 행동이다. 데이터는 단지 행동을 따를 뿐이다.
타입의 계층
그럼 정원사, 병사, 왕자, 공주는 정말로 트럼프인가?
아니다. 단지 트럼프와 몇 가지 특징을 공유하기 때문에 트럼프라고 부른 것이다. 정확히는 '트럼프 인간'이라고 해야할 것이다.
트럼프는 납작 엎드릴 수 있고 뒤집어질 수 있지만, 걷지는 못한다.
이렇듯 트럼프는 트럼프 인간을 포괄한다. 이 관계를 일반화/특수화 관계라고 한다.
트럼트는 더 일반적인 개념(슈퍼타입), 트럼프 인간은 더 특수한 개념(서브타입)이다.
이 때도 일반화/특수화 관계를 결정하는 것은 행동이다.
더 특수한 상태를 나타내느냐가 아닌, 더 특수하게 행동하느냐(걸을 수 있다)로 결정된다.
트럼프는 더 일반적이라 더 큰 크기의 외연 집합을 가지고,
트럼프 인간은 더 특수적이라 더 많은 수의 행동을 가진다.
앨리스는 트럼프 인간을 좀 더 단순화된 트럼프로 일반화했다. 즉, 일반화 또한 추상화를 위한 도구다.
이때까지 추상화를 위한 대표적인 도구 두 가지, 개념과 일반화를 살펴봤다.
초반에 언급한 추상화의 두 차원을 다시 보자.
- 구체적인 사물들 간의 공통점은 취하고 차이점을 버리는 일반화를 통해 단순하게 만드는 것
→ 객체들을 공통의 타입인 트럼프 인간으로 분류 - 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것
→ 트럼프 인간의 불필요한 특성을 배제하고 더 포괄적인 트럼프로 일반화
'기껏해야 트럼프에 불과해.'에서 앨리스는 두 가지 추상화 기법을 사용한 것이다.
타입의 목적은? 정적 모델
왜 타입을 사용하는가? 시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기 어렵기 때문이다.
앨리스의 키는 시간에 따라 동적으로 변하지만, 우리는 시간과 무관한 정적인 모습으로 앨리스 타입을 정의할 수 있다.
즉, 시간이라는 요소를 제거함으로써 정적인 모습을 다룰 수 있게 해준다.
이런 관점에서 또한 타입은 추상화다. 타입을 이용하면 객체의 동적인 특성을 추상화할 수 있다.
객체의 분류라는 추상화면서, 객체 내 불필요한 요소를 제거하는 추상화인 것이다.
우리는 객체를 생각할 때 두 가지 모델을 동시에 고려한다.
- 동적 모델: 객체가 특정 시점에 구체적으로 어떤 상태를 가지느냐(스냅샷)를 포착하는 것
- 정적 모델(타입 모델): 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현하는 것
정적 모델을 구현하는 대표적인 방법이 클래스다.
즉, 클래스는 타입을 구현하는 보편적인 방법 중 하나다.
클래스를 작성하는 시점은 정적인 관점에서 접근하는 것,
실제로 상태 변경을 추적하고 디버깅하는 것은 동적인 관점에서 접근하는 것이다.
우리는 둘 다를 다뤄야 한다.