Books/객체지향의 사실과 오해

객체지향의 사실과 오해 - 타입과 추상화 | 역할, 책임, 협력

devmomori 2022. 8. 31. 19:54

책을 읽으며 객체지향과 더불어 하나의 컴포넌트가 가지게 되는 역할과 책임에 대해서 계속 생각하게 된다. 재사용성이 가능한 컴포넌트를 만들기 위해서 작은 단위의 컴포넌트로 잘게 쪼개는 상황이 생기는데, 이때 조금 더 각각의 컴포넌트들이 역할과 책임을 작게 작게 가져가게 된다. 많은 설명이 개념 중심이라 배운 것들을 어디서 적용해볼지 고민도 많이 해봐야겠다. 결국에는 직접 설계하고 코드를 짜봐야 내 것이 되니깐...

코드를 빨리 짜는 것이 중요한 게 아니라 유지보수성이 뛰어난 애플리케이션을 구축하기 위해서는 견고한 설계가 우선시 되어야 한다.

타입과 추상화

지하철 승객의 목적 : 하나의 역에서 다른 역으로 이동하는 것

승객이 원하는 것 : 빠르게 목적지에 도착할 수 있는지를 직관적이고 단순하게 보여주는 것

 

꼭 알아야하는 사실만 표현하고 몰라도 되는 정보는 무시함으로써 목적에 부합하는 지하철 노선도를 창조 -> 지하철 노선을 추상화

 

모든 경우에 추상화의 목적은 복잡성을 이해하기 쉬운 수준으로 단순화하는 것


이상한 나라의 앨리스의 트럼프

하트 여왕의 행렬에서 나오는 트럼프들을 계급, 나이 , 성격 등의 차이점은 무시하며 '트럼프'라는 유사성을 기반으로 추상화해서 바라봄'

객체지향의 사실과 오해 82쪽 - 앨리스가 추상화한 등장인물들

'기껏해야 트럼프에 불과해'

 

개념(concept): 공통점을 기반으로 객체들을 묶기 위한 그릇

  • 일반적으로 우리가 인식하고 있는 다양한 사물이나 객체에 적용할 수 있는 아이디어나 관념을 뜻한다.
객체란 특정한 개념을 적용할 수 있는 구체적인 사물을 의미한다. 개념이 객체에 적용됐을 때 객체를 개념의 인스턴스라고 한다. (객사오 - 84쪽)

 

 

개념의 세 가지 관점

  • 심볼(symbol): 트럼프 (개념을 가리키는 이름이나 명칭)
  • 내연(intension): 몸이 납작하고 두 손과 발은 네모 귀퉁이에 달려 있는 등장인물 (개념의 완전한 정의, 의미를 통해 개념에 속하는지 여부를 확인)
  • 외연(extension): 정원사, 병사, 왕자, 공주, 하트 여왕 등 (개념에 속하는 모든 객체의 집합)

 

개념은 객체들의 복잡성을 극복하기 위한 추성화 도구이다.

 

객체와 타입

객체는 데이터인가? NO

 

객체에서 중요한 것은 객체의 행동

 

행동이 우선

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

 

같은 타입에 속한 객체는 행동만 동일하다면 서로 다른 데이터를 가질 수 있다. 동일한 행동은 동일한 책임을 의미한다.

 

다형성 : 동일한 요청에 대해 서로 다른 방식으로 응답할 수 있는 능력을 뜻함

 

앨리스가 바라보는 인물들의 행동 방식이 트럼프 카드와 유사하다는 생각을 갖게 만들었고 '트럼프'라는 타입으로 분류했다.

 

객사오 95쪽

 

 

트럼프는 트럼프 인간을 포괄하는 좀 더 일반적인 개념 -> 두 개념 사이의 관계를 일반화/특수화 관계라고 한다.

 

좀 더 일반적인 타입 : 슈퍼타입 (Supertype)

좀 더 특수한 타입 : 서브타입 (Subtype)

 

일반적으로 서브타입은 슈퍼타입의 행위와 호환되기 때문에 서브타입은 슈퍼타입을 대체할 수 있어야한다.

 

 

타입의 목적

앨리스의 키가 변화할 때, 모든 경우의 값을 나열하는 것이 아니라 단순히 키가 임의의 값을 가질 수 있다는 사실만을 생각하면 된다. - 변경되는 키라는 상태를 가진다고 단순화

이런 관점에서 타입은 추상화다

 

객체를 분류하는 기준은 타입 -> 타입을 나누는 기준은 행동 -> 객체 분류를 위해서 타입을 결정한 후 프로그래밍 언어를 이용해 타입을 구현할 수 있는 한 가지 방법이 클래스라는 사실을 기억하자.

 


역할, 책임, 협력

흔히 하는 실수 : 협력이라는 문맥을 고려하지 않은 채 객체가 가져야 할 상태와 행동부터 고민하기 시작한다.

 

객사오 113쪽 - 왕과 하얀 토끼, 모자 장수 사이의 협력 관계 그림

 

등장인물들이 특정한 요청을 받아들일 수 있는 이유는 그 요청에 대해 적절한 방식으로 응답하는 데 필요한 지식과 행동 방식을 가지고 있기 때문이다.

 

책임과 메시지

각각의 등장인물들은 요청을 처리하기 위한 책임을 가지고 있음

 

객체의 책임을 이야기할 때는 일반적으로 외부에서 접근 가능한 공용 서비스의 관점에서 이야기한다. 책임은 객체의 공용 인터페이스를 구성한다.

 

주의할 점 : 책임과 메시지의 수준이 같지 않다. 책임은 객체가 협력에 참여하기 위해 수행해야 하는 행위를 상위 수준에서 개략적으로 서술한 것. 책임을 결정한 후 실제로 협력을 정제하면서 이를 메시지로 변환할 때는 하나의 책임이 여러 메시지로 분할되는 것이 일반적이다.

 

 

설계 초반에는 어떤 객체가 어떤 책임을 가지고 어떤 방식으로 서로 협력해야 하는지에 대한 개요를 아는 것만으로도 충분하다. 책임을 구현하는 방법에 대한 고민은 잠시 뒤로 미뤄도 좋다.

 

 

왕은 판사 / 모자 장수는 증인 - 왜 이렇게 불러서 상황을 복잡하게 만들어야 하나?

역할이 재사용 가능하고 유연한 객체지향 설계를 낳는 매우 중요한 구성요소이기 때문이다.

 

그림으로 보면 좀 더 이해가 쉽다.

 

객사오 123쪽 - 유사한 세 개의 협력과 역할을 통한 단순화한 협력

 

 

이러한 역할의 개념을 사용하면 유사한 협력을 추상화해서 인지 과부하를 줄일 수 있다. 

참고: 인지부하이론의 핵심은 인간의 작동기억에는 한계가 있기 때문에 학습자에게 너무 많은 양의 정보를 한꺼번에 제공하면 인지적 과부하를 일으켜 효과적인 학습을 방해하게 된다는 것이다.

 

다양한 객체들이 협력에 참여할 수 있기 때문에 협력이 좀 더 유연해지며 다양한 객체들이 동일한 협력에 참여할 수 있기 때문에 재사용성이 높아진다. 역할은 객체지향 설계의 단순성, 유연성, 재사용성을 뒷받침하는 핵심 개념이다.

 

추가적으로, 객체는 역할이 암시하는 책임보다 더 많은 책임을 질 수 있다.

  • 왕은 재판도하고 국정도 돌본다.
  • 모자 장수는 증인이지만 모자를 판매하는 본질적인 책임이 있다.

 

객체의 모양을 결정하는 협력

시스템에 필요한 데이터를 저장하기 위해 객체가 존재한다? -> NO

객체가 상태의 일부로 데이터를 포함하지만, 데이터는 단지 객체가 행위를 수행하는 데 필요한 재료일 뿐이다.

 

클래스와 클래스 간의 관계를 표현하는 시스템의 정적인 측면에 중점 -> NO

중요한 것은 협력에 참여하는 동적인 객체이며, 클래스는 단지 시스템에 필요한 객체를 표현하고 생성하기 위해 프로그래밍 언어가 제공하는 구현 메커니즘이라는 사실을 기억하자.

 

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

 

 

객체지향 설계 기법

책임-주도 설계 : 협력에 필요한 책임들을 식별하고 적합한 객체에게 책임을 할당

 

디자인 패턴 : 반복적으로 사용하는 해결 방법을 정의해 놓은 설계 템플릿의 모음

 

테스트-주도 개발 : 테스트를 먼저 작성하고 테스트를 통과하는 구체적인 코드를 추가하면서 애플리케이션을 완성해가는 방식

  • 테스트가 아니라, 설계를 위한 기법이다. 실제 목적은 구체적인 코드를 작성해나가면서 역할, 책임, 협력을 식별하고 적합한지 피드백 받기 위함이다.