[객체지향의 사실과 오해] 3장

2020. 4. 13. 21:52책/객체지향의 사실과 오해

 

3장 타입과 추상화 

일단 컴퓨터를 조작하는 것이 추상화를 구축하고, 조작하고, 추론하는 것에 관한 모든것이라는 것을 깨닫고 나면

컴퓨터 프로그램을 작성하기 위한 중요한 전제 조건은 추상화를 정확하게 다루는 능력이라는 것이 명확해진다. -키스 데블린

 

해리 벡의 지하철 노선도

해리 벡이 창조한 지하철 노선도

위의 사진은 1933년 해리 벡이 내놓은 지하철 노선도이다. 

매우 오래된 노선도임에도 불구하고 현재 서울의 지하철 노선도를 보는것과 크게 다르지 않은 느낌이다.

사실 해리 벡이 창조한 지하철 노선도는 역의 순서와 갈아타는 역의 표시를 제외하면 어느 것 하나 정확한 것이 없다.

모든 역의 위치와 거리도 부정확하고, 심리어 경로를 표시한 직선은 실제로 지하철이 이동하는 경로와는 상관이 없다.

그럼에도 해리 벡이 제시한 지하철 노선도의 기본적인 개념과 원형은 70여년이 지난 현재까지도 커다란 수정 없이 

전 세계 지하철 노선도에 적용되고 있다.

그럴 수 있는 이유는 무엇일까? 이 책에서는 그 답을 '추상화'에 두었다.

지하철을 이용하는 승객의 목적은 하나의 역에서 다른 역으로 이동하는 것이다. 해리 벡의 지하철 노선도는 이러한 '목적'에 집중한 결과물이다.  연결, 즉 열차를 갈아타는 것에 포커스를 둔 것이다.

실제로 해리 벡은 지하철을 이용하는 승객들을 면밀하게 관찰한 후 승객이 꼭 알아야 하는 사실만 정확하게 표현하고, 몰라도 되는 정보는 무시하는 과정을 거쳐 이러한 지하철 노선도를 완성하였다.

 

 

추상화를 통한 복잡성 극복

해리 벡의 지하철 노선도가 70여년이 지난 현재까지도 쓰이고 있는 이유는, 그 목적성에 특화되어 추상화 되었기 때문이다.

그렇다면 추상화는 무엇일까? 

추상화란 어떤 양상, 세부사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법이다. 객체지향 설계의 측면에서 보면, 현실에서 출발하되 불필요한 부분을 도려내가면서 사물의 놀라운 본질을 드러나게 하는 과정이라고 할 수 있겠다. 

이 책에서는 이러한 추상화가 두 차원에서 이뤄진다고 말하고 있다.

첫째, 구체적인 사물들 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순하게 만든다.

둘째, 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만든다.

그리고 이러한 추상화의 목적은 '복잡성'을 이해하기 쉬운 수준으로 '단순화'하는 것이다.

 

객체지향과 추상화

이상한 나라의 앨리스를 다시 떠올려보자,

2장에서 앨리스는 행동을 통해 자신의 '키'라는 상태를 줄여 '위치'라는 상태를 정원안으로 바꾸었다. 

문을 통과했다는 뜻이다.

앨리스는 정원에서 페인트칠을 하고 있는 트럼프 카드 세장을 마주한다.

이후에 그 옆으로 트럼프 병사들, 트럼프 공주와 왕자, 트럼프 하객, 트럼프 왕과 왕비들의 행렬이 지나간다.

이 이야기에서 각각의 트럼프들은 서로 다른 트럼프이다. 

하지만 앨리스는 왕이든 신하든 백성이든 '기껏해야 트럼프에 불과해'라고 생각한다.

이와같이 공통점을 기반으로 객체들을 묶기 위한 그릇을 개념이라고 표현하고 있다. 

개념이란 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 뜻한다.

인간의 인지능력과 저장공간은 한계가 있기 때문에 특정 개념을 적용하는데에 아주 익숙하다.

예를들어 길거리를 지나다니는 교통수단에 '자동차'라는 개념을 적용시키고, 하늘을 지나다니는 교통수단에 '비행기'라는 개념을 적용시키는 것 처럼 말이다. 각 자동차와 비행기는 서로 다른 객체임에도 우리는 그것에 개념을 적용시켜서 간단하게 인지 할 수 있다. 

이러한 개념을 이용하면 객체를 여러 그룹으로 분류할 수 있다. 그리고 각 개념 그룹의 일원이 될때 그 객체를 인스턴스라고 한다. 따라서, 객체를 특정한 개념을 적용할 수 있는 구체적인 사물이라고 정의할 수도 있겠다. 

 

개념

정리를 하면서도 아직 개념이라는 개념(?)이 아직 모호하다. 

다행히 책에서는 이러한 나를 위해 개념을 더 잘게 쪼개어서 설명해 주었다.

개념은 세가지의 관점으로 설명할 수 있는데 심볼, 내연, 외연이 바로 그것이다.

심볼이란 개념을 가리키는 간략한 이름이나 명칭이다.

내연은 개념의 완전한 정의를 나타내며 내연의 의미를 이용해 객체가 개념에 속하는지 여부를 확인할 수 있다. 즉, 조건이다.

외연은 개념에 속하는 모든 객체의 집합을 말한다.

책의 문장을 빌려 위의 세가지 관점을 모두 설명하자면,

앨리스가 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 왕과 하트 왕비의 몸이 납작하고 두 손과 발이 네모 귀퉁이에 달려있기 때문에 트럼프라는 개념으로 묶었다.

위의 문장에서 '트럼프'는 '심볼이다' 

몸이 납작하고 두 손과 발이 네모 귀퉁이에 달려있어야한다는 조건은 '내연'이다.

이렇게 '트럼프'라는 개념으로 묶인 정원사,병사,신하, ... 등은 외연이다.

추상화를 위해서는 다양한 각각들을 하나로 묶어 분류를 해야하는데, 이러한 분류를 하기 위한 틀이 바로 개념이 되는 것이다.

 

타입

개념이라는 말은 우리의 일상생활에서도 이미 폭넓게 사용되고 있다. 

이러한 개념이라는 말을 컴퓨터 공학에서는 타입이라고 부른다.

타입은 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 의미하는데, 어떤 객체에 타입을 적용할 수 있을때 그 객체를 타입의 인스턴스라고 한다.

말이 좀 어렵지만, 결론적으로 애플리케이션 안에서 여러 데이터를 분류하기 위해 타입이 사용된다고 생각하면 되겠다.

메모리 내부의 값들은 모두 0과 1 로 이루어져있기 때문에 이러한 데이터들이 숫자인지 문자열인지 등을 구분해주기 위한 메타데이터라고 생각하자.

이러한 타입은 어떻게 결정될까?

첫째, 어떤 객체가 어떤 타입에 속하는지를 결정하는 것은 객체가 수행하는 행동이다.

즉, 어떠한 연산을 하는가? 이다. 숫자가 숫자일 수 있는 이유가 서로 더하고 빼고 곱하고 나눌수가 있기 때문이고,

문자열이 문자열일 수 있는 이유는 문자들을 붙이거나 떼거나 할 수 있기 때문이다. 

둘째, 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다. 단지, 객체의 행동을 가장 효과적으로 수행하는 것이 중요하다. 같은 행동을 할 수 있다면 내부의 상태와 관계없이 같은 타입이라고 할 수 있다. 

 

행동이 우선!

위의 두가지로부터 객체지향 설계를 함에있어서 중요한것이 역시 행동이라는 것을 알 수 있었다. 

결론적으로 객체의 타입을 결정하는 것은 객체의 행동뿐이다. 객체가 어떤 데이터를 보유하고 있는지는 타입을 결정하는데 아무런 영향을 미치지 않는 것이다.

그렇다면 같은 타입에 속한 객체는 동일한 행동을 한다는 의미인데, 동일한 행동이란 무엇일까?

앞장에서 행동이란 객체 스스로가 어떠한 요청메세지에 대하여 반응하는 것이라고 하였다. 

동일한 행동을 한다는것은 동일한 요청메세지에 대한 처리를 할 수 있다는 의미이다. 물론 그 메시지를 처리하는 방식은 내부의 표현 방식이 다르기때문에 다를 수 밖에없다. 이것이 나중에 생각해볼 다형성에 의미를 부여하는 것이다.

간단히 집고 넘어가자면, 다형성은 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 뜻한다. 

대학교 수업에서 이 다형성에 대해 배울때 많이 헷갈렸었는데, 이 책을 통해서 쉽게 이해할 수 있어서 참 좋았던 부분이다.

또 하나 생각해볼 것은 데이터 타입을 결정하는데에 있어서 행동만을 고려해야 하므로, 내부 표현방식은 감춰지는 것이 좋다.

이러한 설계를 캡슐화라고 부른다. 행동이 아닌 내부 데이터가 외부에 노출 되는 것은 객체의 자율성을 침해할 수 있으므로, 유연성을 떨어뜨리는 설계를 낳을 수 있겠다.

이 단락에서, 다시한번 새기게 된 사실은 객체를 결정하는 것이 행동이라는 것이다.

데이터는 단지 행동을 따를 뿐이다. 이것이 객체를 객체답게 만드는 가장 핵심적인 원칙이다.

 

타입의 계층

앨리스의 이야기에서 트럼프 타입에 대해 이야기하였다.

그들이 트럼프 타입일 수 있는 이유는 트럼프가 할 수 있는 행동인 내연의 조건을 만족했기 때문이다.

즉, 행동에 의해 타입이 결정 된 것이다.

하지만, 이야기에서 트럼프에 해당하는 왕,왕자,왕비,공주 등은 말을하고 걷기까지한다.

트럼프의 조건을 만족하면서 추가적으로 인간의 조건까지 만족하는 이것들을 '트럼프 인간'이라고 해보자.

트럼프 인간은 트럼프의 모든 행동을 그대로 할 수 있으면서 추가적인 행동들까지 할 수 있다.

이러한 관계를 일반화/특수화 관계라고 한다.

트럼프가 트럼프 인간보다 일반적인 개념이므로 슈퍼타입이라고 하고,

더 특수한 트럼프 인간을 서브타입이라고 책에서는 부르고 있다.

이때, 어느것이 슈퍼이고 서브인지를 결정하는것 또한 행동이다. 서브타입에 해당하는 객체들은 슈퍼타입의 모든 행동을 그대로 실행할 수 있으며, 거기에 추가적인 행동들을 할 수 있는 것이다. 

이렇게 슈퍼타입과 서브타입을 나누는 필요성에 대해서는 어렵지 않게 떠올릴 수 있다. 

A라는 행동을 할 수 있는 객체와 A와 B라는 행동을 할 수 있는 객체가 있을때, A는 공통적인 행동이다.

어딘가에선 A와 C , A와 D, A와 E라는 행동을 할 수 있는 객체들이 있을 수 있다. 

그만큼 A가 일반적인 경우 사용되는 행동이라면 당연히 각각의 타입을 독립적으로 만들기보다는, A타입을 만든후 그것을 각각에서 구체화 시키는 것이 편리하고, 유지보수가 쉬울 것이다.

 

그래서 결국 타입은 추상화다

앞서 추상화는 불필요한 정보를 제거하고 공통적인 특징을 강조하여 분류할 수 있다고 하였다.

타입은 시간에 따라 동적으로 변하는 객체의 상태를 시간과 무관한 정적인 모습으로 다룰 수 있게 해준다.

시간이라는 복잡성과 시간에 따른 상태변화 라는 더 복잡한 요소를 제거하고 철저하게 정적인 관점에서 객체의 모습을 묘사하는 것이 가능해진다는 것이다.

예컨데, 앨리스의 키라는 상태가 시간이 흐름에 따라 100cm, 400cm, 30cm, 1cm가 될 수 있는 것을

앨리스라는 타입에 시간에 따라 바뀔 수 있는 상태 '키'가 있다. 라고 단순화 시킬 수 있는 것이다. 

 

 

느낀점

그렇다면 타입과 클래스는 같은 말일까?

타입 ... 타입은 객체를 분류하기 위해 사용되는 개념이다.

클래스... 클래스는 객체를 분류하지 못하는가? 

이 책을 읽기전의 나라면 두 개념을 정말 혼동했을 것이다.

하지만, 클래스가 타입을 구현하기 위한 여러가지 구현 메커니즘 중 하나라는 것을 알게 되었다.

실제로 자바스크립트와 같은 프로토타입 기반의 언어에 클래스가 없지 않은가.

그럼에도 내가 사용 하는 언어로 객체지향 프로그래밍을 하다보면 클래스를 기반으로 모든 설계가 이루어지기 때문에, 두 개념은 또한번 나를 혼란에 빠뜨릴 것이다. 

이 책에서 말하는 것처럼 객체를 분류하는 기준이 타입이고, 타입을 나누는 기준이 객체가 수행하는 행동이라는 사실만을 기억하자. 객체를 분류하기 위해 타입을 결정한 후에 그 타입을 구현하는데에 사용되는 방법이 클래스이다. 

프로그래밍을 하다보면 타입이라는 개념은 또 희미해지고 나는 클래스를 설계하고 있을 것이다. 

그럴때마다 위의 두 문장을 떠올릴 수 있으면 좋겠다. 

 

3장끝