[객체지향] 객체지향의 사실과 오해(토끼책) Ch1 ~ 3 정리

2022. 2. 5. 00:41TIL💡/Design Pattern

객체들 간의 관계성(우아한형제들 블로그 참조)

01. 협력하는 객체들의 공동체

흔히 객체 지향이 실세계의 투영이며, 객체란 현실 세계에 존재하는 사물에 대한 추상화라고 한다.

그러나 객체 지향의 목표는 실세계를 모방하는 것이 아니다.

오히려 새로운 세계를 창조하는 것이다.

객체 세계 현실 세계 효과
객체 스스로 생각하고 스스로 결정하는 현실세계의 생명체 캡슐화(Encapsulation)하는 소프트웨어 객체(Autonomous)의 자율성 설명
협력 현실 세계의 사람들이 암묵적인 약속과 명시적인 계약을 기반으로 협력하며 목표를 달성하는 과정 메시지를 주고 받으며 공동의 목표를 달성하기 위해 협력하는 객체들의 관계 설명
협력을 위해 특정한 역할을 맡고 역할에 적합한 책임을 수행한다.

협력의 개념

  • 여러 사람이 동일한 역할을 수행할 수 있다.
  • 역할은 대체 가능성을 의미한다.
  • 책임을 수행하는 방법은 자율적으로 선택할 수 있다.
  • 한 사람이 동시에 여러 역할을 수행할 수 있다.

객체의 덕목

  • 객체는 충분히 협력적이어야 한다.
  • 객체는 충분히 자율적이어야 한다.

 

객체의 특징

  • 객체는 다른 객체와 협력하기 위해 메시지를 전송한다.
  • 메시지를 수신한 객체는 메시지를 처리하는 데 메서드를 자율적으로 선택한다.

02. 이상한 나라의 객체

객체 지향의 목적

  • 현실세계를 모방하는 것이 아니라 현실 세계를 기반으로 새로운 세계를 창조

객체의 구성

  • 상태(state)
    • property: 객체의 상태를 구성하는 모든 특징
  • 행동(behavior)
    • 객체에 접근할 수 있는 유일한 방법
    • 명령(Command): 객체의 상태를 변경하는 작업
    • 쿼리(Query): 객체의 상태를 조회하는 작업
  • 식별자(identity)

 

행동이 상태를 결정한다

상태를 먼저 결정하고 행동을 나중에 결정하는 방법은 설계에 나쁜 영향을 끼친다.

Why?

1. 상태를 먼저 결정할 경우 캡슐화 저해

공용 인터페이스에 그대로 노출되어버릴 확률이 높아지기 때문

 

2. 객체를 협력자가 아닌 고립된 섬으로 만듦

객체가 필요한 이유 = 애플리케이션의 문맥 내에서 다른 객체와 협력

상태를 먼저 고려하는 방식은 협력이라는 문맥에서 멀리 벗어난 채 객체 설계하기 때문

 

3. 객체의 재사용성 저하

객체의 재사용성은 다양한 협력에 참여할 수 있는 능력에서 나온다.

상태에 초점을 맞춘 객체는 다양한 협력에 참여하기 어렵기 때문

 

따라서 행동을 생각한 후 행동을 수행할 객체를 선택하는 방식으로 수행된다.

행동 결정 → 행동에 필요한 정보 고려 → 필요한 상태 결정

 

책임-주도 설계

협력 안에서 객체의 행동은 결국 객체가 협력에 참여하며 완수해야하는 책임을 의미


03. 타입과 추상화

추상화

어떤 양상, 세부 사항, 구조를 좀 더 명확하게 이해하기 위해 특정 절차나 물체를 의도적으로 생략하거나 감춤으로써 복잡도를 극복하는 방법

복잡성을 다루기 위해 추상화는 두 차원에서 이뤄진다.

  • 첫 번째 차원 - 구체적인 사물들 간의 공통점은 취하고, 차이점은 버리는 일반화를 통해 단순하게 만드는 것
  • 두 번째 차원 - 중요한 부분을 강조하기 위해 불필요한 세부사항 제거

이는 모두 복잡성을 이해하기 쉬운 수준으로 단순화하는 것이다.

 

개념(Concept)

공통점을 기반으로 객체들을 묶기 위한 그릇

 

세 가지 관점

  • 심볼: 개념을 가리키는 이름
  • 내연: 개념의 의미
  • 외연: 개념의 인스턴스들이 모여 이뤄진 집합

타입과 객체의 유사성

타입의 특징 객체의 특징
연산자의 종류가 아니라 어떤 데이터에 어떤 적용할 수 있느냐가 그 데이터의 타입을 결정한다. 동일한 행동을 수행하는 객체는 동일한 타입으로 분류
타입에 속한 데이터를 메모리에 어떻게 표현하는지는 외부로부터 철저하게 감춰진다. 객체의 내부적인 표현은 외부로부터 철저하게 감춰진다.

슈퍼타입과 서브타입

객체 지향에서 일반화/특수화 관계를 결정하는 것은 객체의 상태가 아니라 객체의 행동에 따라 결정된다.

일반적인 타입을 슈퍼타입이라 하고, 좀 더 특수한 타입을 서브타입이라 한다.

어떤 타입이 다른 타입의 서브타입이 되기 위해서, 행위적 호환성을 만족해야한다.

즉 서브타입은 슈터타입을 대체할 수 있어야 한다.

 

왜 타입을 사용하는가?

시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기 위함

타입을 쓰면 객체의 상태는 변하나(키 = 140cm, 180cm...), 다른 객체와 구별할 수 있는 식별성은 동일하게 유지된다.

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

→ 타입은 추상화!

 

클래스

객체 지향 프로그래밍 언어에서 정적인 모델은 클래스를 이용해 구현된다.

객체를 구현하는 가장 보편적인 방법은 클래스 이용하나, 타입과 클래스는 동일한 개념이 아니다.

 

타입은 객체를 분류하기 위해 사용하는 개념일 뿐!(객체 식별)

클래스는 단지 타입을 구현할 수 있는 여러 구현 매커니즘 중 하나일 뿐!