이번 챕터에서는 지하철 노선도를 예시로 들며 시작한다.
지하철 노선도 디자인에서 가장 중요한 것은 얼마나 사실적으로 지형을 묘사했느냐가 아니라 역과 역 사이의 연결성을 얼마나 직관적으로 표현했느냐 이다
- 초기 지하철 노선도
- 실제와 유사한 구불구불한 운행 노선과 불규칙적인 역간의 거리를 사실 적으로 묘사
- 이해가 어려움
- 현대 지하철 원형 디자인(해리 벡)
- 사실적인 지형과 축척은 무시하고 역 사이의 연결성에만 집중
- ‘정확성’을 버리고 ‘목적’에 집중하여 이해하기 쉽고 목적에 부합하는 지하철 노선도를 창조
- 지하철 노선을 추상화 한 것
1. 추상화를 통한 복잡성 극복
여기서도 역시 추상화를 통한 복잡성 극복 예시로 해리 벡의 지하철 노선도를 설명한다.
- 헤리 벡이 고안한 추상화가 유용했던 이유 → 승객들이 지하철을 바라보는 모델과 일치했기 때문
- 승객들이 지하철을 이용하는 이유와 해리 벡이 지형 정보를 제거한 이유는 동일 → 역의 위치가 중요한 것이 아니라 역과 역 사이의 연결 관계가 중요했던 것
이 책에서는 추상화를 다음과 같이 정의한다.
추상화
어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법
- 복잡성을 다루기 위해 추상화는 두 차원에서 이루어짐
- 첫 번째 차원은 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만드는 것
- 두 번째 차원은 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것
- 모든 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것
🔆 객체지향 패러다임은 객체라는 추상화를 통해 현실의 복잡성을 극복하고, 객체지향 패러다임을 이용해 추상화의 두 차원을 올바르게 이해하고 적용하는 것이 중요
2. 객체 지향과 추상화
객체지향 패러다임과 추상화의 관계를 설명하기 위해 이상한 나라의 앨리스 예시를 들고 있다.
🟡 그룹으로 나누어 단순화하기
- 객체지향 패러다임에서는 명확한 경계를 가지고 서로 구별할 수 있는 구체적인 사람이나 사물을 객체라고 함
- 이상한 나라의 앨리스에서 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트왕과 하트 여왕은 서로 다른 객체
- ‘기껏해야 트럼프에 불과해’: 앨리스 이야기에서의 추상화
- 앨리스의 이야기에서 앨리스는 토끼를 제외한 모든 등장인물을 트럼프라고 한다.
- ‘트럼프’와 ‘토끼’라는 두 개의 렌즈를 통해 정원을 바라보는 것은 정원에 내재된 복잡성을 효과적으로 감소시킴
- 인물들의 차이점을 무시하고, 공통점만을 취해 트럼프라는 개념으로 단순화 → 추상화 (첫번째 차원)
🟡 개념
- 공통점을 기반으로 객체들을 묶기 위한 그릇으로 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념
- 객체들 중에서 몸이 납작하고 두 손과 두 발이 네모난 몸 모서리에 달려 있는 객체 → ‘트럼프’ 라는 개념 적용 (추상화)
- 개념을 이용하면 객체를 여러 그룹으로 분류할 수 있음
- 객체에 어떤 개념을 적용하는 것이 가능해서 개념 그룹의 일원이 될 때 객체를 그 개념의 인스턴스라고 함
- 정원사, 병사, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕이라는 객체는 트럼프라는 개념의 인스턴스 인 것 !
🔆 객체란 특정한 개념을 적용할 수 있는 구체적인 사물을 의미하며, 개념이 객체에 적용됐을 때 객체를 개념의 인스턴스라고 함.
🟡 개념의 세 가지 관점
- 심볼(symbol): 개념을 가리키는 간략한 이름이나 명칭
- 내연(intension): 개념의 완전한 정의를 나타내며, 내연의 의미를 이용해 객체가 개념에 속하는지 여부를 확인 가능
- 몸이 납작하고 두 손과 두 발은 네모 귀퉁이에 달려 있는 등장인물
- 외연(extension): 개념에 속하는 모든 객체의 집합(개념의 인스턴스들이 모여 이뤄진 집합)
- 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕
🔆 개념을 이용해 객체를 분류할 수 있다는 사실은 중요 → 해당 아이디어는 객체지향 패러다임이 복잡성을 극복하는 데 사용하는 가장 기본적인 인지 수단이기 때문
🟡 객체를 분류하기 위한 틀
- 분류란 객체에 특정한 개념을 적용하는 작업으로, 객체에 특정한 개념을 적용하기로 결심했을 때 우리는 그 객체를 특정한 집합의 멤버로 분류하고 있는 것
- 객체는 최대한 직관적으로 분류하는 것이 중요
- 객체를 적절한 개념에 따라 분류한 애플리케이션은 유지보수가 용이하고, 변경에 유연하게 대처할 수 있음.
🟡 분류는 추상화를 위한 도구다
- 개념을 통해 객체를 분류하는 과정은 추상화의 두 가지 차원을 모두 사용하므로 분류는 추상화를 위한 도구다
- 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕을 트럼프라는 개념으로 묶은 것은 개별 객체 간의 차이점은 무시하고 공통점을 취한 결과로 첫 번째 차원인 일반화를 적용한 결과
- 트럼프에 속하는 객체들의 공통점 중에서도 중요하다고 생각한 특징은 몸이 납작하고 두 손과 두 발이 네모난 몸 모서리에 달려 있는 것으로 다른 불필요한 세부 사항을 제거한 것은 두 번째 차원을 적용한 결과
- 따라서, 개념은 객체들의 복잡성을 극복하기 위한 추상화 도구
3. 타입
🟡 타입은 개념이다
- 타입은 개념과 동일 → 컴퓨터 공학자들이 개념을 좀 더 멋지게 표현하기 위해 가져온 용어
- 따라서 타입은 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념
- 어떤 객체에 타입을 적용할 수 있을 때 그 객체를 타입의 인스턴스라고 하며, 타입의 인스턴스는 타입을 구성하는 외연인 객체 집합의 일원이 됨
🟡 데이터 타입
- 메모리 안에 저장된 데이터의 종류를 분류하는 데 사용하는 메모리 집합에 대한 메타데이터
- 데이터에 대한 분류는 임시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정
- 어떤 데이터에 어떤 연산자를 적용할 수 있느냐가 그 데이터의 타입을 결정
🔆 그래서 데이터 타입은 왜 쓰는거야?
타입 시스템은 메모리 안에 저장된 0과 1에 대해 수행가능한 작업과 불가능한 작업을 구분함으로써 데이터가 잘못 사용되는 것을 방지
🟡 객체와 타입/행동이 우선이다
- 객체를 타입에 따라 분류하고 그 타입에 이름을 붙이는 것은 결국 프로그램에서 사용할 새로운 데이터 타입을 선언하는 것과 같음
- 그래서 객체는 데이터인가?
- No
- 1) 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동
- 어떤 객체들이 동일한 행동을 수행할 수 있다면, 그 객체들은 동일한 타입으로 분류될 수 있음
- 2) 객체의 내부적인 표현은 외부로부터 철저하게 감춰짐
- 객체의 행동을 가장 효과적으로 수행할 수만 있다면 객체 내부의 상태를 어떤 방식으로 표현하더라도 무방함
- 1),2)로부터 객체지향 설계에 대한 중요한 원칙을 이끌어낼 수 있음
- 결과적으로 동일한 행동(책임)을 수행하는 일련의 객체는 동일한 타입에 속함!
- 객체의 타입을 결정하는 것은 객체의 행동뿐이며, 객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는 데 아무런 영향도 미치지 않음
🔆 동일한 행동=동일한 책임=동일한 메시지 수신
- 동일한 타입에 속한 객체는 내부의 데이터 표현 방식이 다르더라도 동일한 메시지 수신하고, 처리할 수 있어야 하므로 동일한 메시지를 처리하는 방식은 서로 다를 수 밖에 없음
- 다형성: 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력
- 동일한 메시지를 서로 다른 방식으로 처리하기 위해서 객체들은 동일한 메시지를 수신할 수 있어야 하므로 다형적인 객체들은 동일한 타입에 속하게 됨
- 데이터의 내부 표현 방식과 무관하게 행동만이 고려 대상이라는 사실은 외부에 데이터를 감춰야 한다는 것을 의미
- 행동에 따라 객체를 분류하기 위해서는 객체가 내부적으로 관리해야 하는 데이터가 아니라 객체가 외부에 제공해야 하는 행동을 먼저 생각해야 함
- 이를 위해 객체가 외부에 제공해야 하는 책임을 먼저 결정하고, 그 책임을 수행하는 데 적합한 데이터를 나중에 결정한 후, 데이터를 책임을 수행하는 데 필요한 외부 인터페이스 뒤로 캡슐화해야 함
- 이를 책임-주도 설계라고 함
🔆 객체를 결정하는 것은 행동이며, 데이터는 단지 행동을 따를 뿐이다.
4. 타입의 계층
🟡 트럼프 계층
- 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕은 정말 트럼프인가?
- 외양은 트럼프와 유사하지만 행동 자체는 트럼프와 완별하게 동일 x
- 트럼프 카드는 납작 엎드릴 수 있고 뒤집어질 수 있지만 걸어다닐 수는 없음 따라서 트럼프 인간이라는 타입으로 분류하는 것이 옳음
- 트럼프 인간은 트럼프다. 따라서 트럼프는 트럼프 인간을 포괄하는 좀 더 일반적인 개념이다. 이 두 개념 사이의 관계를 일반화/특수화 관계라고 한다
🟡 일반화/특수화 관계
- 일반화와 특수화는 동시에 일어남
- 객체지향에서 일반화/특수화 관계를 결정하는 것은 객체의 상태를 표현하는 데이터가 아니라 행동
- 두 타입 간에 일반화/특수화 관계가 성립하려면 한 타입이 다른 타입보다 더 특수하게 행동해야 하고 반대로 한 타입은 다른 타입보다 더 일반적으로 행동해야 한다. ]
- 행동의 관점에서 일반적인 타입/특수한 타입
- 일반적인 타입: 특수한 타입이 가진 모든 행동들 중에서 일부 행동만을 가지는 타입
- 특수한 타입: 일반적인 타입이 가진 모든 타입을 포함하지만 거기에 더해 자신만의 행동을 추가하는 타입
- 단, 특수한 타입은 일반적인 타입이 할 수 있는 모든 행동을 동일하게 수행할 수 있어야 함
❓ 일반적인 타입은 특수한 타입보다 외연의 크기는 더 크고 행동의 수는 더 적다?
외연의 크기가 크단 말이 특수한 타입이 일반적인 타입의 부분 집합이 되므로, 집합의 크기가 더 크다는 말일까?
🟡 슈퍼타입과 서브타입
- 일반적인 타입=슈퍼타입, 특수한 타입=서브타입
- 어떤 타입이 다른 타입의 서브타입이 되기 위해서는 행위적 호환성을 만족시켜야함
- 서브타입은 슈퍼타입의 행위와 호환되기 때문에 서브타입은 슈퍼타입을 대체할 수 있어야 함
- 일반화/특수화 관계 표기법
- 슈퍼타입을 상단, 서브타입을 하단에 위치시키고 속이 빈 삼각형을 연결해서 표현
- 서브타입에서는 슈퍼타입과 중복된 행위를 생략 가능
- 슈퍼타입의 행동은 서브타입에게 자동으로 상속
🟡 일반화는 추상화를 위한 도구다
- 일반화/특수화 계층은 객체지향 패러다임에서 추상화의 두번째 차원을 적절하게 활용하는 대표적인 예
- ‘기껏해야 트럼프에 불과해’: 그 시점에 중요한 사항인 트럼프의 특성에만 집중하고 불필요한 트럼프 인간의 특성은 제거
5. 정적 모델
🟡 타입의 목적
- 인간의 인지 능력으로는 시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기가 너무 어렵기 때문
- 계속해서 변하는 앨리스의 키를, 앨리스의 키가 임의의 값을 가질 수 있다는 사실만을 생각함으로써 상황을 단순하게 만들 수 있음
- 따라서 타입은 시간에 따라 동적으로 변하는 앨리스의 상태를 시간과 무관한 정적인 모습을 다룰 수 있게 해줌
🟡 그래서 결국 타입은 추상화다
- 앨리스에 관해 생각할 때 불필요한 시간이라는 요소와 상태 변화라는 요소를 제거하고 철저하게 정적인 관점에서 앨리스의 못브을 묘사하는 것을 가능하게 해주니까! → 추상화 두번째 차원
🟡 동적 모델과 정적 모델
- 동적 모델
- 실제로 객체가 살아 움직이는 동안 상태가 어떻게 변하고 어떻게 행동하는지를 포착하는 것
- 정적 모델(타입 모델)
- 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현하는 것
- 동적으로 변하는 객체의 상태가 아니라 객체가 속한 타입의 정적인 모습을 표현
🟡 클래스
- 타입을 구현하는 가장 보편적인 방법은 클래스를 이용하는 것
- 객체지향에서 중요한 것은 동적으로 변하는 객체의 상태와 상태를 변경하는 행위이며, 클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘