일단 컴퓨터를 조작하는 것이 추상화를 구축하고, 조작하고, 추론하는 것에 관한 모든 것이라는 것을 깨닫고 나면 (훌륭한) 컴퓨터 프로그램을 작성하기 위한 중요한 전제 조건은 추상화를 정확하게 다루는 능력이라는 것이 명확해진다. - 키스 데블린(Keith Devlin)[Devlin 2003]
요즘날의 지하철은 거미줄처럼 매주 복잡하게 얽혀있다. 하지만 승객들은 큰 어려움없이 이용하고 있는데, 이 이유는 단순하고 직관적으로 역 간의 네트워크를 표현하는 지하철 노선도가 있기 때문이다.
현대적인 지하철 노선도의 원형을 디자인 한 사람은 영국의 해리 벡(Harry Beck)인데, 헤리 벡이 디자인한 노선도를 보면 기존의 노선도보다 정보전달에 있어 훨씬 효과적이었다.
기존 사실적인 것에 집중한 지하철 노선도와 달리 헤리 벡의 지하철 노선도는 ‘정확성’을 버리고 그 ‘목적’에 집중했기 때문에, 승객이 꼭 알아야 하는 사실만 정확하게 표현하고 몰라도 되는 정보를 무시해 이해하기 쉽고 더 목적에 부합하는 지하철 노선도가 되었다.
이는 지하철 노선를 ‘추상화’한 것이다.
추상화란?
- 현실에서 불필요한 부분을 배제, 사물의 본질을 드러나게 하는 과정이라고 할 수 있다.
추상화의 목적
- 불필요한 부분을 무시함으로써 현실에 존재하는 복잡성을 극복하는 것 → 현실의 단순화
객체지향 패러다임은 객체라는 추상화를 통해 현실의 복잡성을 극복한다.
이상한 나라의 앨리스에 위와 같은 장면이 나오며, 앨리스를 향한 위압적인 상황에서 앨리스는 마음속으로 이렇게 속삭였다. ‘기껏해야 트럼프에 불과해. 무서워할 필요 없어.’
이 장면에서는 앨리스, 클로버병사, 신하, 왕비등은 모두 객체이다. 이 객체들은 제각기 독특한 모습과 행동 양식을 지니고 있다.
하지만, 앨리스의 대사에서 이 객체들 대부분을 하나로 아울러 생각하고 있다.
앨리스는 모든 객체를 ‘트럼프’라는 하나의 개념으로 단순화해서 바라보고 있는 것이다.
각 객체의 차이점은 과감하게 무시하고 공통점만 취해 단순화해버렸다.
각 인물의 계급, 나이, 성격 등의 차이점은 무시한 채 ‘트럼프’라는 유사성을 기반으로 추상화해서 바라보고 있는 것이다.
객체 지향 패러다임에는 구체적이고 실제적인 객체가 존재하지만 수많은 객체들을 개별적인 단위로 취급하기에는 인간이 지닌 인지능력이 턱없이 부족하다.
사람들은 본능적으로 공통적인 특성을 기준으로 객체를 여러 그룹으로 묶어 동시에 다뤄야 하는 가짓수를 줄이고 상황을 단순화하려고 노력한다.
이런 공통점을 기반으로 객체들을 묶기 위한 그릇을 **개념(concept)**이라고 한다.
개념이란, 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 뜻한다.
ex) 도로위 교통수단 → 자동차, 하늘을 나는 교통수단 → 비행기, 앨리스 이야기에서의 트럼프
개념을 이용하면 객체를 여러 그룹으로 분류(classification)할 수 있다.
이 분류 안에서 각 구체적인 객체는 그룹의 일원으로 포함되고, 이 그룹의 일원을 개념의 인스턴스(instance)라고한다.
객체란 특정한 개념을 적용할 수 있는 구체적인 사물을 의미한다. 개념이 객체에 적용됐을 때 객체를 개념의 인스턴스라고 한다.
- 심볼(symbol): 개념을 가리키는 간략한 이름이나 명칭
- 내연(intension): 개념의 완전한 정의를 나타내며 내연의 의미를 이용해 객체가 개념에 속하는지 여부를 확인할 수 있다.
- 외연(extension): 개념에 속하는 모든 객체의 집합(set)
트럼프라는 개념의 심볼, 내연, 외연은 다음과 같이 표현할 수 있다.
- 심볼: 트럼프 ⇒ 개념을 가리키는 이름
- 내연: 몸이 납작하고 두 손과 두 발은 네모 귀퉁이에 달려 있는 등장인물 ⇒ 개념의 의미
- 외연: 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕 ⇒ 개념에 속하는 객체들
- 어떤 객체를 어떤 개념으로 분류할지가 객체지향의 품질을 결정한다.
- 객체를 적절한 개념에 따라 분류하지 못한 애플리케이션은 유지보수가 어렵고, 변화에 쉽게 대처하지 못한다.
- 객체를 적절한 개념에 따라 분류한 애플리케이션은 유지보수가 용이하고 변경에 유연하게 대처할 수 있다.
- 적절한 분류 체계는 개발자의 머릿속에 객체를 쉽게 찾고 조작할 수 있는 정신적인 지도를 제공한다.
타입(type)의 정의는 개념의 정의와 완전히 동일하다.
- 타입은 공통점을 기반으로 객체들을 묶기 위한 틀이다.
- 개념과 마찬가지로 심볼, 내연, 외연을 이용해 서술 가능하다.
- 타입에 속하는 객체 역시 타입의 인스턴스라고 한다.
메모리 상에는 0,1의 비트열로만 구성되어 있으며, 타입이라는 것이 없다.
데이터를 구분하기 위해 데이터의 목적에 따라 분류하기 시작했고, 프로그래밍 언어 안에는 타입 시스템(type system)이 자리잡기 시작했다.
타입시스템의 목적
- 메모리 안의 모든 데이터가 비트열로 보임으로써 야기되는 혼란을 방지하는 것
타입의 특징
- 타입은 데이터의 사용 용도에 관한 것이다.
- 더하거나 뺄수 있는 숫자형인가?, 두 데이터를 연결해 새로운 문자열을 만들 수 있는 문자열형인가?
- 타입에 속한 데이터를 어떻게 표현하는지는 외부로부터 철저하게 감춰 진다.
- 개발자는 메모리 내부에 숫자가 어떤 방식으로 저장되는지 몰라도 연산자와 데이터를 사용해 숫자형 데이터를 사용할 수 있다.
데이터 타입의 정의
- 데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는 데 사용하는 메모리 집합에 관한 메타데이터다. 데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는지를 결정한다.
객체지향 프로그램에서 우리는 객체를 일종의 데이터처럼 사용한다. 따라서 객체를 타입에 따라 분류하고 객체에 이름을 붙이는 것은 결국 프로그램에서 사용할 새로운 데이터 타입을 선언하는 것과 같다.
객체는 데이터인가?
- 그렇지 않다. 객체에서 중요한 것은 객체의 행동이다.
- 상태는 행동의 결과로 초래된 부수효과를 표현하기 위해 도입한 추상적인 개념
- 객체를 창조할 때 중요한 것은 객체가 이웃하는 객체와 협력하기 위해 어떤 행동을 해야 할지를 결정하는 것이다.
- 객체가 협력을 위해 어떤 책임을 지녀야 하는지를 결정하는 것이 객체 지향 설계의 핵심이다.
객체의 타입에 대한 조언 (== 데이터 타입의 특징)
- 어떤 객체가 어떤 타입에 속하는지 결정하는 것은 객체가 수행하는 행동
- 어떤 객체들이 동일한 행동을 수행할 수 있다면, 동일한 타입으로 분류가능하다
- 객체의 내부적인 표현은 외부로 부터 철저하게 감춰진다.
- 객체의 행동을 수행할 수 있다면 객체 내부의 상태를 어떤 방식으로 표현해도 무방하다.
- 객체의 타입을 결정하는 것 → 객체의 행동
- 객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는 데 아무런 영향도 미치지 않는다.
-
같은 타입에 속한 객체는 행동만 동일하다면 서로 다른 데이터를 가질 수 있다.
-
다만 내부의 표현 방식이 다르기 때문에 동일한 메시지를 처리하는 방식은 서로 다를 수 밖에 없다 ⇒ 다형성
다형성: 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력
-
- 행동만이 고려대상이라는 사실은 외부에 데이터를 감춰야 한다는 것을 의미
- 객체지향 설계는 외부에 행동만을 제공하고 데이터는 행동 뒤로 감춰야 한다 ⇒ 캡슐화
- 데이터가 객체의 캡슐밖으로 나와 인터페이스를 오염시키는 순간 유연하지 못한 설계를 초래한다.
- 객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는 데 아무런 영향도 미치지 않는다.
타입은 일반적인 타입과 특수한 타입으로 나눌 수 있는데, 특수한 타입이란 일반적인 타입의 부분집합의 개념이다.
특수한 타입인 트럼프 인간은 일반적인 타입(트럼프)이면서 더 많은 행동을 가지며, 일반적인 타입이 할 수 있는 행동을 동일하게 수행할 수 있다.
이 두 개념 사이의 관계를 일반화/특수화(generalization/specializtion)관계라고 한다.
일반적인 타입 ⇒ 슈퍼타입(Supertype)
특수한 타입 ⇒ 서브타입(Subtype)
서브타입은 슈퍼타입의 행위와 호환된다. 즉, 서브타입은 슈퍼타입을 대체할 수 있어야 한다.
타입을 사용해야 하는 이유
- 인간의 인지 능력으로는 시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기 어렵기 때문
- 타입은 시간에 따라 동적으로 변하는 앨리스의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해준다.
- 타입을 이용하면 객체의 동적인 특성을 추상화할 수 있다. 결국 타입은 시간에 따른 객체의 상태 변경이라는 복잡성을 단순화할 수 있는 효과적인 방법인 것이다.
- 스냅샷처럼 실제로 객체가 살아 움직이는 동안 상태가 어떻게 변하고 어떻게 행동하는지 포착하는 것을 동적 모델(dynamic model)이라고 한다.
- 다른 하나는 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현하는 것 → 타입 모델
- 이 모델은 동적으로 변하는 객체의 상태가 아니라 객체가 속한 타입의 정적인 모습을 표현하기 때문에 **정적 모델(static model)**이라고도 한다
객체지향 프로그래밍 언어에서 정적인 모델은 클래스를 이용해 구현된다.
타입을 구현하는 가장 보편적인 방법은 클래스를 이용하는 것이다.
- 클래스와 타입은 동일한 것이 아니다.
- 타입은 객체를 분류하기 위해 사용하는 개념
- 클래스틑 단지 타입을 구현할 수 있는 여러 구현 매커니즘 중 하나일 뿐
다만, 대부분의 프로그래밍 언어는 클래스를 기반으로 하기 때문에 동일한 개념이라고 생각할 뿐이다.
클래스는 타입의 구현 외에도 코드를 재사용하는 용도로도 사용되기 때문에 클래스와 타입을 동일시 하는 것은 지양하는 것이 좋다.
객체를 분류하는 기준은 타입이며, 타입을 나누는 기준은 객체가 수행하는 행동.
프로그래밍 언어에서 객체를 분류하기 위한 한 가지 방법이 클래스라는 사실을 알아야 한다.