Chapter 03. 타입과 추상화


훌륭한 프로그램을 작성하기 위한 중요한 전제 조건은 추상화를 정확하게 다루는 능력

지하철 노선도의 목적은 열차를 어디에서 갈아타는지에 대한 ‘연결성’이지 얼마나 사실적인 척도를 가지는지에 대한 ‘정확성’이 아니다.

현대 지하철 노선도를 제안한 ‘해리 벡’의 ‘지하철 노선도 추상화’에 대한 내용이다

추상화를 통한 복잡성 극복


현실은 복잡하며 예측 불가능한 혼돈의 덩어리다.

초기조건에 대한 민감성으로 설명되는 나비효과는 현실의 복잡성을 이해하고 예측하는 것이 얼마나 어려운지를 잘 설명해 주는 적절한 메타포다.

복잡성의 총체인 ‘현실’이라는 괴물을 그대로 수용하기에는 인간이 지니고 있는 인지 능력과 저장 공간이 너무나도 보잘것없다.
따라서 사람들은 본능적으로 이해하기 쉽고 예측 가능한 수준으로 현실을 ‘분해’하고 ‘단순화’하는 전략을 따른다.
‘해리 벡’의 지하철 노선도가 유용했던 이유는 ‘역 사이의 연결성’이라는 승객들이 지하철을 바라보는 모델과 일치했기 때문이다.

이렇듯, 추상화의 목적은
불필요한 부분을 무시함으로써 현실에 존재하는 복잡성을 극복하는 것이며,
추상화의 수준, 이익, 가치는 ‘목적’에 의존한다.

추상화는 복잡한 것을 단순화하는 것이다.

그룹으로 나누어 단순화하기


앨리스는 < 이상한 나라의 앨리스 >에 등장하는 정원사, 병사, 신하, 왕자와 공주, 하객으로 참석한 왕과 왕비들, 하트 잭, 하트 왕과 하트 여왕과 같이 트럼프의 의미에 적합한 인물은 ‘트럼프’라고 그룹 짓고, 의미에 적합하지 않은 ‘토끼’는 트럼프 그룹에서 제외했다.

이처럼 트럼프 그룹의 인물들을 차이점은 과감하게 무시하고 공통점만을 취해 ‘트럼프’라는 그룹으로 ‘단순화’했다.
그리고 이러한 그룹화는 ‘개념’이라고 한다. 우리가 인식하는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념이다.

‘개념’은 각각의 객체의 세부적인 복잡성을 극복하기 위한 도구이다.
예를 들어, ‘자동차’라는 개념은 수많은 각각의 자동차 객체를 단순화해 그룹화한다.
일반적인 자동차의 모양, 4개의 바퀴, 창문이 달리고, 운전자가 있으며 .. 등등

< 이상한 나라의 앨리스 >에 등장하는 하얀 토끼도 ‘토끼’라는 개념 그룹의 일원이다.
이러한 그룹의 일원을 ‘인스턴스’라고 한다.

분류는 추상화를 위한 도구다


위에서 ‘트럼프’, ‘자동차’, ‘토끼’라는 개념으로 각각의 개념을 그룹화해 ‘분류’했다.
이러한 분류는 ‘추상화’를 위한 도구이다.

추상화는 두 가지 차원에서 이루어진다.

  1. 구체적인 객체 간의 공통점은 취하고 차이점은 버리는 일반화를 통해 단순화하는 것.
  2. 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거해 단순화하는 것.

객체를 분류하는 과정은 추상화의 두 가지 차원을 모두 사용한다.

< 이상한 나라의 앨리스 >에 등장한 ‘트럼프’ 그룹은
몸이 납작하고 두 손과 두 발이 네모난 몸 모서리에 달려있다는 공통점만으로 분류된 결과물이다.
객체의 이외의 특성에 대해서는 앨리스의 이야기를 풀어나가는 데 어떤 도움도 되지 않기 때문에
불필요한 세부 사항을 무시한 체 단순화한다.

타입은 개념이다


메모리의 100010001은 무엇을 나타내는 데이터일까?

타입 없는 무질서가 초래한 혼돈의 세상에 질려버린 사람들은 급기야 메모리 안의 데이터에 특정한 의미를 부여하기 시작했다. 사람들은 자신이 다뤄야 하는 데이터의 용도와 행동에 따라 그것들을 분류했다.

더하거나 빼거나 나누거나 곱할 수 있다면 ‘숫자형’
여러 문자로 구성돼 있고 다른 문자와 연결될 수 있다면 ‘문자열형’
참/거짓을 이야기할 수 있다면 ‘논리형’으로 분류할 수 있다.

이렇게 데이터를 ‘목적’에 따라 분류하기 시작하면서 ‘타입 시스템’이 자라나기 시작했다.

객체와 타입


객체지향 프로그램을 작성할 때 우리는 객체를 일종의 ‘데이터’처럼 사용한다.
따라서 객체를 타입에 따라 분류하고 그 타입에 이름을 붙이는 것은 결국 프로그램에서 사용할 새로운 데이터 타입을 선언하는 것과 같다.

객체는 행위에 따라 변할 수 있는 상태를 가지고 있다.
프로그램 내부에 살고 있는 모든 객체의 상태를 모으면 결국 프로그램에서 관리해야 하는 전체 데이터를 표현할 수 있게 된다.

  1. 객체가 ‘어떤 타입’에 속하는지를 결정하는 것은 객체가 수행하는 ‘행동’이다. 객체가 동일한 행동을 수행할 수 있다면 그 객체들은 ‘동일한 타입’이다.
  2. 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다. 객체의 행동을 가장 효과적으로 수행할 수만 있다면 객체 내부의 상태를 어떤 방식으로 표현해도 무방하다.

행동이 우선이다


객체가 어떤 행동을 하느냐에 따라 객체의 타입이 결정된다.
객체의 내부 표현과는 아무런 상관이 없다.

타입이 데이터가 아니라 행동에 의해 결정된다는 사실은 객체지향 패러다임을 특징짓는 중요한 몇 가지 원리와 원칙에 의미를 부여한다.

동일한 타입에 속한 객체는 동일한 메시지를 수신하고 이를 처리할 수 있다.
내부의 표현 방식이 다르더라도 메시지를 처리하는 ‘방식’에 차이가 있지 동일한 메시지를 처리한다는 사실은 변함없다.

이것은 객체지향의 ‘다형성’에 관한 내용이다.
다형성이란 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 뜻한다.

결과적으로 다형적인 객체들은 동일한 타입에 속하게 된다.

앨리스가 ‘트럼프’를 동일한 타입으로 분류한 이유는 그들이 동일한 방식에 따라 행동했기 때문이다.
종이처럼 납작 엎드릴 수 있고, 강한 바람에 뒤집어질 수 있으며, 네모 귀퉁이에 손과 발이 달렸기 때문에 걸을 때마다 종이 같은 몸이 좌우로 펄럭거린다.

인물들의 동일한 행동 방식은 앨리스로 하여금 이들이 트럼프와 유사하다는 생각을 갖게 만들었고
이를 ‘트럼프’라는 ‘타입’으로 분류한 것이다.

객체를 결정하는 것은 행동이다.
데이터는 단지 행동을 따를 뿐이다.

이것이 객체를 객체답게 만드는 가장 핵심적인 원칙이다.

트럼프 계층


앞에서 ‘트럼프’는 사실 ‘트럼프인간’이 더 적합한 분류이다.
왜냐하면 트럼프의 모습인 종이처럼 납작하고 뒤집어질 수 있는 공통점을 가지고 분류했는데,
일반적으로 트럼프는 걸어 다닐 수 없고 팔과 다리도 없다. 따라서 우리는 ‘트럼프 인간’이라는 ‘타입’으로 분류하는 것이 옳다.

‘트럼프 인간’ 타입의 객체는 ‘트럼프’ 타입의 객체가 할 수 있는 모든 행동을 할 수 있을 뿐만 아니라 추가적으로 걸어 다니는 행동을 더 할 수 있다.

이러한 관계에는 ‘일반화 / 특수화 관계’가 적용되며,
일반적인 타입을 ‘슈퍼타입’ 특수한 타입을 ‘서브타입’이라고 한다.

C++ 객체지향 프로그래밍에서 상위 클래스의 함수를 호출할 때 _Super.Func()로 호출한다.
C# 객체지향 프로그래밍에서는 base.Func()

타입의 목적


< 이상한 나라의 앨리스 >에서 앨리스의 키는 계속 변하고 있었지만 모든 경우에 앨리스는 단지 앨리스일뿐이었다.

상태(데이터)는 변하지만 앨리스를 다른 객체와 구별할 수 있는 식별성은 동일하게 유지된다.

앨리스라는 객체는 ‘키’라는 데이터가 100cm, 80cm, 40cm, 300cm, 등
동적으로 변하는 객체의 상태를 ‘변경되는 키’라는 ‘상태’를 가진다고 하면
동적인 상태를 정적인 관점에서 표현할 수 있다.

정적 모델과 동적 모델


객체가 살아 움직이는 동안 상태가 어떻게 변하고 어떻게 행동하는지를 포착하는 것을 ‘동적 모델’이라고 한다. 또 하나는 객체가 가질 수 있는 모든 상태와 모든 행동을 시간에 독립적으로 표현하는 것을 ‘정적 모델’이라고 한다.

객체지향 프로그래밍 언어를 이용해 클래스를 작성하는 시점에는 시스템을 ‘정적인 관점’에서 접근하는 것이고,
프로그램을 실행해 객체의 상태 변경을 추적하고 디버깅하는 동안에는 객체의 ‘동적인 모델’을 탐험하는 것이다.

이 두 모델을 적절히 다뤄야 한다는 사실을 쉽게 이해할 수 있을 것이다.

마무리


객체를 분류하는 기준은 ‘타입’이며, 타입을 나누는 기준은 객체가 수행하는 ‘행동’이라는 사실을 기억하라.
그리고 타입을 구현하는 한 가지 메커니즘이 ‘클래스’라는 사실을 잊지 말자.

결국 객체지향에서 중요한 것은 동적으로 변하는 객체의 ‘상태’와 상태를 변경하는 ‘행동’이다.

Chapter 04. 역할, 책임, 협력


우리 모두를 합친 것보다 더 현명한 사람은 없다.

경제학에서는 인간을 이기적인 동시에 합리적인 존재라고 가정한다.

어느 날 한 교수가 흥미로운 경제학 게임을 제안했다.
이름은 ‘최후 통첩 게임’이다.

제안자와 응답자 2명이 게임을 진행하며, 게임이 시작할 때 제안자에게 거액의 금액이 주어진다.
제안자는 이 거액의 금액을 응답자와 나누어 가져야 하며, 원하는 만큼 나눠줄 수 있다.
이때 경제학에서 바라보는 인간의 관점으로는 응답자에게 최대한 적은 금액을 주고, 나는 최대한 많은 금액을 취하려 할 것이다.

하지만 실험 결과는 받은 금액의 40% 이상의 금액을 제안했다.

이기적인 욕심을 누르고 40% 내지 50%에 달하는 큰 비율의 금액을 제안할 수밖에 없었던 이유는,
각 개인이 처해 있는 정황 또는 문맥(Context)이 인간의 행동 방식을 결정하기 때문이다.

이 게임에 나온 인간은 감정적으로 대응한다. 자존심을 지키기 위해 불공정한 제안을 단호히 거절한다.

제안자는 응답자의 이러한 성향을 예측하고 있기 때문에 많은 비율의 금액을 응답자에게 제안하는 경우가 가장 많다.

여기서 인간의 행동을 결정하는 문맥은 ‘타인과의 협력’이다.
협력이라는 문맥을 무시한 채 각 개인의 반응을 독립적으로 예상하고 관찰하는 것은 무의미하다.

최후 통첩 게임은 ‘협력 게임’인 것이다.


객체 지향의 세계에서도 ‘협력’이라는 ‘문맥’이 객체의 행동 방식을 결정한다.

객체지향에 갓 입문한 사람들의 가장 흔한 실수는 문맥을 고려하지 않은 채
객체가 가져야 할 상태와 행동부터 고민하기 시작한다는 것이다.

  1. ‘협력’이 자리 잡으면
  2. 저절로 ‘행동’이 드러나고
  3. 뒤이어 ‘상태’가 결정된다.

훌륭한 객체지향 설계란 오만한 객체를 창조하는 것이 아니라,
조화를 이루며 적극적으로 상호작용하는 협력적인 객체를 창조하는 것이다.

“객체들 간의 협력에 집중하라”

협력과 책임


객체지향의 세계는 동일한 목적을 달성하기 위해 협력하는 객체들의 공동체이다.
그리고 요청과 응답은 ‘협력’에 참여하는 객체가 수행할 책임을 정의한다.

어떤 객체가 어떤 요청에 대해 대답해 줄 수 있거나, 적절한 행동을 할 의무가 있는 경우
해당 객체가 ‘책임’을 가진다고 말한다.

앨리스의 이야기에서 왕은 ‘재판을 수행하라’는 요청에 응답하기 위해 ‘재판을 수행할’ 책임을 지게 된다.
하얀 토끼의 경우에는 ‘목격자를 불러오라’는 요청에 응답해야 하므로 ‘목격자를 불러올’ 책임을 지게 되고,
모자 장수는 ‘증인석에 입장’하고 ‘증언할’ 책임을 지게 된다.

결국 어떤 대상에 대한 요청은 그 대상이 요청을 처리할 ‘책임’이 있음을 암시한다.

객체지향 개발에서 가장 중요한 능력은 ‘책임’을 능숙하게 소프트웨어 객체에 할당하는 것

책임을 어떻게 구현할 것인가 하는 문제는 객체와 책임이 제자리를 잡은 후에 고려해도 늦지 않다.
책임은 객체지향 설계의 품질을 결정하는 가장 중요한 요소다.
객체지향 설계의 예술은 적절한 객체에게 적절한 책임을 할당하는 데 있다.

책임이 불분명한 객체들은 애플리케이션의 미래 역시 불분명하게 만들며,
명확한 책임이 애플리케이션의 미래를 결정짓는다.

설계를 시작하는 초반에는 어떤 객체가 어떤 책임을 가지고 어떤 방식으로 서로 협력해야 하는지에 대한 개요를 아는 것만으로도 충분하다.

책임과 협력의 구조가 자리를 잡기 전까지는 책임을 구현하는 방법에 대한 고민은 잠시 뒤로 미루는 것이 좋다.

그리고 역할


앨리스의 이야기에서 모자 장수는 ‘증인’이라는 역할을 수행하고 왕은 ‘판사’라는 역할을 수행하고 있다.
굳이 왕을 ‘판사’라고 부르고 모자 장수를 ‘증인’이라고 불러서 상황을 복잡하게 만드는 이유는 무엇인가?
그것은 ‘역할’이 ‘재사용 가능’하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소이기 때문이다.

앨리스의 이야기에서 재판이라는 ‘협력’이 이루어지는 동안
‘판사’이라는 역할은 왕 객체 -> 여왕 객체
‘증인’이라는 역할은 모자 장수 객체 -> 앨리스 객체
위와 같은 ‘객체의 대체’만 있을 뿐, 재판이 이뤄지는 과정이 완벽하게 동일하다.

  1. 판사에게 재판을 요청
  2. 판사가 하얀 토끼에게 증인을 부를 것을 요청
  3. 하얀 토끼는 증인에게 증인석 입장을 요청
  4. 증인이 증인석 입장 후, 판사가 증인에게 증언을 요청
  5. 증인은 자신이 알고 있는 내용을 증언

위의 과정은 재판이라는 ‘협력’에서
판사와 하얀 토끼 그리고 증인이라는 ‘역할’의 재사용성이 돋보이는 사례이다.

매번 바뀌는 재판이라는 협력 과정을 일일이 수정할 필요는 없다.
따라서 ‘판사’와 ‘증인’이라는 ‘역할’을 사용하면,
‘여러 협력’을 모두 포괄할 수 있는 ‘하나의 협력’으로 ‘추상화’할 수 있다.

왕과 여왕이 ‘판사’의 역할을 수행할 수 있는 이유는
‘판사’가 수신할 수 있는 ‘재판하라’라는 메시지를 동일하게 이해하고 처리할 수 있기 때문이다.

‘행동’이 타입을 결정한다. 동일한 메시지를 처리하면, 동일한 타입을 사용할 수 있다.

이처럼 ‘역할’은 객체지향 설계의 ‘단순성’, ‘유연성’, ‘재사용성’을 뒷받침하는 핵심 개념이다.

협력의 추상화


앨리스 이야기에서

  1. 왕 - 하얀 토끼 - 모자 장수
  2. 왕 - 하얀 토끼 - 요리사
  3. 왕 - 하얀 토끼 - 앨리스

이 세 가지 재판의 경우에서
객체는 각각 ‘판사’, ‘하얀 토끼’, ‘증인’이라는 ‘역할’을 부여받는데,
재판 또한 ‘추상적인 협력’으로 대체할 수 있다.

추상적인 역할을 대체해서 동일한 구조의 협력을 다양한 문맥에서 재사용할 수 있는 능력은
과거의 전통적인 패러다임과 구분되는 객체지향만의 힘이다.

흔한 오류


  1. 시스템에 필요한 데이터를 저장하기 위해 객체가 존재한다는 선입견을 가지고 있다.
    • 데이터는 단지 객체가 행위를 수행하는 데 필요한 재료일 뿐이다.
    • 객체가 존재하는 이유는 행위를 수행하며 협력에 참여하기 위해서다.
    • 따라서 실제로 중요한 것은 객체의 ‘행동’, 즉 ‘책임’이다.
  2. 객체지향이 클래스와 클래스 간의 관계를 표현하는 시스템의 정적인 측면에 중점을 둔다는 선입견이다.
    • 클래스는 단지 시스템에 필요한 객체를 표현하고 생성하기 위해 프로그래밍 언어가 제공하는 ‘구현 메커니즘’이다.

객체지향 입문자들이 데이터나 클래스를 중심으로 애플리케이션을 설계하는 이유는
‘협력’이라는 ‘문맥’을 고려하지 않고, 각 객체를 독립적으로 바라보기 때문이다.
예를 들어, ‘왕’의 인스턴스를 모델링할 경우 멋진 수염과 근엄한 표정으로 왕좌에 앉아 있는 모습부터 떠올릴 것이다.

하지만 실제로 동작하는 애플리케이션을 구축하기 위해서는 ‘왕이 참여하는 협력’을 우선적으로 고려해야 한다.

앨리스의 이야기에서 왕이 중요한 이유는 ‘재판이라는 협력’에, ‘판사의 역할’로 참여해서 죄인의 ‘죄를 판결하는 책임’을 수행할 수 있기 때문이다.

협력을 따라 흐르는 객체의 책임


올바른 객체를 설계하기 위해서는 먼저 견고하고 깔끔한 협력을 설계해야 한다.

‘협력을 설계한다는 것’은 객체들이 주고받을 ‘요청과 응답의 흐름을 결정’한다는 것을 의미한다.
이렇게 결정된 요청과 응답의 흐름은 객체가 ‘협력에 참여하기 위해 수행될 책임’이 된다.

‘협력이라는 문맥’에서 객체가 수행하게 될 ‘적절한 책임’, 즉 행동을 결정한 후에,
그 행동을 수행하는 데 ‘필요한 데이터’를 고민해야 한다.

공동의 목표 -> 협력(요청과 응답) -> 적절한 책임(행동) -> 데이터 설정 -> 클래스 개발

객체지향 설계 기법


  1. 책임-주도 설계
  2. 디자인 패턴
  3. 테스트-주도 개발

Chapter 05. 책임과 메시지


< 나중에 작성 예정 >

느낀 점


앞에서 등장한 내용인 역할, 책임, 협력의 관점에서 다시 한번 객체지향을 설명하는 듯한 느낌을 받았습니다.

  1. 역할 / 타입 / 개념
  2. 책임 / 행동
  3. 협력 / 메시지(요청과 응답)
  4. 상태 / 데이터

위 내용은 이 책에서 객체지향을 설명하기 위해서 등장하는 같은 개념의 단어끼리 묶어 나열해 보았습니다.
틀린 부분 있으면 지적해 주세요:)

논의할 점


디자인 패턴이란 자주 발생하는 문제, 즉 특정 패턴에 대한 문제 해결 패러다임이라 알고 있습니다. 객체지향 설계 기법에서 ‘디자인 패턴’에 대한 내용이 나오는데,
자신의 필요에 의해서 디자인 패턴을 찾아본 경험이 있나요?

카테고리:

업데이트:

댓글남기기