2024.11.04

객체지향의 사실과 오해를 읽으며

image

ch01을 읽으며 기록한 문장들

  • p31 협력 속에 사는 객체

    • 객체는 전지전능한 역할이 되어서는 안됨 -> 다른 객체의 요청에 응답
    • 자기 스스로의 원칙에 따라 어떤 일을 하거나 자기 스스로를 통제하여 절제하는 것 -> 자율적인 객체
    • 캐시어는 손님이 주문하면 행동 -> 손님에게 음료를 주문하는 절차나 바리스타에게 접수 내역을 전달하는 방법은 스스로 결정 -> 손님이 캐시어에게 어떤 질문을 하거나, 주문 내역을 어떤 방식으로 전달해달라고 지시하지 않음 -> 캐시어는 자율적인 존재
  • p32 상태, 행동을 지닌 객체

    • 객체는 상태(state)와 행동(behavior)을 함께 지닌 실체
    • 협력에 참여하기 위해 어떤 행동을 행동을 하는데 필요한 상태도 함께 지니고 있어야 함
    • 커피를 제조하는 바리스타가 제조하는 법을 모를 수 없음 -> 어떤 행동을 하기 위해 필요한 상태 알지 못함 -> 말이 안됨
    • 객체는 다른 객체가 무엇(what)을 수행하는지 알수 있음 -> 어떻게(how) 수행하는지는 알 수 없음
    • 자율적인 객체로 구성된 공동체 -> 유지보수가 쉽고 재사용이 용이한 시스템을 구축할 가능성 제시

p35 객체지향의 본질

  • 자율적인 객체들의 공동체
  • 상태와 행위를 함께 지니며 스스로 자기 자신을 책임지는 객체
  • 행위를 구현하기 위해 다른 객체와 협력, 정해진 역할 수행 -> 역할은 책임의 집합
  • 다른 객체와 협력하기 위해 메시지 전송 , 메시지 수신한 객체 -> 적합한 메서드를 자율적으로 선택

p37 객체지향은 클래스(class)에 대한 착각

  • 객체지향 선구자들의 초기 의도와 달리 대부분의 사람들은 객체 지향을 클래스를 지향하는 것 이라고 생각함 -> 클래스에 대한 중요성이 과하다 싶을 정도로 강조됨 -> 조금씩 부풀려짐
  • 클래스를 정의하는 방법, 클래스 사이의 상속에 초점을 맞춤 -> UML의 대표적인 다이어그램을 클래스 다이어그램을 떠올림, 하지만 객체지향 분석/설계의 목적은 훌륭한 클래스를 식별하는 것
  • 객체지향의 핵심을 이루는 중심개념은 아님 클래스가 -> 자바스크립트 같은 프로토타입(prototype) 기반 객체지향 언어는 클래스가 존재하지 않음 -> 오직 객체만 존재함 -> 이런 언어 속의 상속 역시 클래스가 아닌 객체 간의 위임(delegation) 메커니즘을 기반으로 함
  • 지나치게 클래스를 강조하면 -> 객체의 캡슐화를 저해 , 클래스를 서로 강하게 결합 시킴 -> 객체들의 공동체가 아니라 클래스로 구성된 설계도로 보는 관점은 유연하고 확장 가능한 애플리케이션 구축을 방해함
  • 어떤 클래스가 필요하지 x -> 어떤 객체들이 어떤 메시지를 주고받으며 협력하는가
  • 클래스는 객체들의 협력 관계를 코드로 옮기는 도구에 불과 , 클래스는 객체지향 세계의 도시 전설
  • 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것 -> 협력에 참여하는 객체를 만드는데 필요한 구현 메커니즘 -> 협력 구조와 책임을 식별하는 것에 비해 덜 중요하다는 말 -> 메시지를 주고받는 객체들의 동적인 관계
  • 클래스의 구조와 메서드가 아님 -> 객체의 역할, 책임, 협력에 집중

ch02를 읽으며 기록한 문장들

이상한 나라의 객체

p47

  • 객체를 상태(state), 행동(behavior), 식별자(identity)를 지닌 실체로 보는 것이 가장 효과적이다.

  • 객체란 식별 가능한 개체 또는 사물이다.

  • 객체는 자동차처럼 만질 수 있는 구체적인 사물일 수도 있고, 시간처럼 추상적인 개념일 수도 있다.

  • 객체는 구별 가능한 식별자, 특징적인 행동, 변경 가능한 상태를 가진다.

  • 소프트웨어 안에서 객체는 저장된 상태와 실행 가능한 코드를 통해 구현된다.

상태

p48

  • 상태를 이용하면 과거에 얽매이지 않고 현재를 기반으로 객체의 행동 방식을 이해할 수 있다.
  • 세상의 복잡성을 완화하고 인지 과부하를 줄일 수 있는 중요한 개념이다.

p50

  • 객체의 상태를 구성하는 모든 특징을 통틀어 객체의 프로퍼티(property)은 정적
  • 프로퍼티 값(proeprty value)은 시간이 흐름에 따라 변경되어서 동적
  • 객체와 객체 사이의 의미 있는 연결을 링크(link)라고 한다. 요청을 보내고 받을 수 있다.
  • 객체를 구성하는 단순한 값은 속성(attribute)이라고 한다.

p51

  • 객체는 자율적인 존재라는 점을 명심하라.
  • 객체는 다른 객체의 상태에 직접적으로 접근할 수도, 상태를 변경할 수도 없다. 자율적인 객체는 자신의 상태를 책임져야 한다.
행동

p50

  • 객체의 행동은 상태를 변경시키지만 행동의 결과는 상테에 의존적이다.
    • ex) 음료를 마신 후의 앨리스의 키는 음료를 마시기 전의 앨리스의 키보다 작아져야 한다.
    • ex) 앨리스가 문을 통과할 수 있는지는 앨리스의 키가 현재 몇 센티미터인지에 달려 있다. 앨리스의 키가 문보다 크다면 문을 통과할 수 없을 것이다.

객체의 행동은 상태에 영향을 받는다. 객체의 행동은 상태를 변경시킨다.

  • 행동을 어떻게 서술할 것인가

    • 상호작용이 현재의 상태에 어떤 방식으로 의존하는가
    • 상호작용이 어떻게 현재의 상태를 변경시키는가
      • ex) 앨리스의 키가 40센티미터 이하라면 문을 통과할 수 있다.
      • ex) 문을 통과한 후에 앨리스의 위치는 아름다운 정원으로 바뀌어야 한다.
  • 행동이란 외부의 요청 또는 수신된 메시지에 응답하기 위해 동작하고 반응하는 활동이다. 행동의 결과로 객체는 자신의 상태를 변경하거나 다른 객체에게 메시지를 전달할 수 있다. 객체는 행동을 통해 다른 객체와의 협력에 참여하므로 행동은 외부에 가시적이어야 한다.

p55- 56

캡슐화는 객체의 상태를 캡슐 안에 감춰둔 채 외부로 노출하지 않고, 행동만 노출한다. 객체에 접근할 수 있는 유일한 방법은 역시 행동뿐이다.

객체의 행동을 유발하는 것은 외부로부터 전달된 메시지이다.

상태를 외부에 노출시키지 않고 행동을 경계로 캡슐화하는 것은 결과적으로 객체의 자율성을 높인다.

p57

식별자

  • 객체를 서로 구별할 수 있는 특정한 프로퍼티가 객체 안에 존재한다

  • 값(value)은 숫자, 문자열, 날짜, 시간, 금액 등과 같이 변하지 않는 양을 모델링한다. 흔히 값은 상태가 변하지 않아 불변 상태(Immutable State)를 가진다고 말한다.

    • 상태를 이용해 두 값이 판단하는 성질을 동등성(equality)이라고 한다.
    • 값의 상태는 결코 변하지 않기 때문에 동등성을 판단할 수 있다.
  • 식별자를 기반으로 객체가 같은지를 판단할 수 있는 성질을 동일성(identical) 이라고 한다.

p64

행동이 상태를 결정한다.

대부분의 초보자들이 객체에 필요한 상태를 먼저 결정하고 행동을 나중에 결정하는 방법을 취하는데 이는 설계에 나쁜 영향을 끼친다.

이유:

상태를 먼저 결정할 경우 캡슐화가 저해된다. 상태가 객체 내부로 깔끔하게 캡슐화되지 못하고 공용 인터페이스에 그대로 노출되버릴 확률이 높다.

객체의 재사용성이 저하된다. 다양한 협력을 이룰려면 재사용성이 좋아야되는데 상태에 초점을 맞추면 다양한 협력에 참여하기 어렵다.

객체지향 설계는 애플리케이션에 필요한 협력을 생각하고 협력에 참여하는 데 필요한 행동을 생각한 후 행동을 수행할 객체를 선택하는 방식으로 수행된다.

결국 객체가 협력에 참여하면서 완수해야 하는 책임을 의미한다.

이 책에서는 책임-주도 설계(Responsibility-Driven Design, RDD)

2장의 핵심 : **행동이 상태를 결정한다.

은유와 객체

p66

추상화(abstraction)란 실제의 사물에서 자신이 원하는 특성만 취하고 필요 없는 부분을 추려 핵심만 표현하는 행위

다양한 객체를 모방하여 필요한 부분만 취해(추상화) 소프트웨어 객체로 구현 객체지향은 현실 세계의 추상화

객체지향 세계는 현실 세계의 단순한 모방이 아니다

  • 소프트웨어 안에 창조하는 객체에게 현실 세계의 객체와는 전혀 다른 특징을 부여하는 것이 일반적이다.
    • 현실 객체가 가지지 못한 추가적인 능력을 보유하도록 한다. 이것을 소프트웨어 객체의 특징인 의인화(anthropomorphism) 이라고 한다.
    • 궁극적인 목적은 현실과 전혀 다른 새로운 세계를 창조하는 것이다.

객체지향 분석/설계는 현실 세계의 객체를 자세히 관찰하고 그중에서 소프트웨어 객체에 적합한 속성만 추려내라는 것이다.

**은유

  • 실제로는 적용되지 않은 한 가지 개념을 이용해 다른 개념을 서술하는 대화의 한 형태
  • 그리스어로 transfer(옮기다)에서 유래됨
  • 하나의 의미를 다른 것을 이용해 전달한다
  • 현실 세계인 도메인에서 사용되는 이름을 객체에게 부여하라는 가이드 지침과 비슷하다

타입과 추상화

p74

  • 해리 벡의 지하철 노선도 추상화
    • 지하철을 이용하는 분들의 목적은 하나의 역에서 다른 역으로 이동하는 것, 어떤 역에서 출발해야 하는지와 어떤 역에서 환승해야 하는지, 그리고 어떤 역을 거쳐야만 가장 쉽고 빠르게 목적지에 도착할 수 있는지를 직관적이고 단순하게 보여주는 것.

p77

**추상화

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

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

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

  • 두 번째 차원은 중요한 부분을 강조하기 위해 불필요한 세부 사항을 제거함으로써 단순하게 만드는 것이다.

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

p78

모두 트럼프일 뿐

  • 앨리스 앞에 왕자, 여왕, 신하들, 하객, 하얀 토끼 와 같은 다양한 객체들이 등장하였으나, 하얀 토끼를 제외한 모든 것들은 트럼프일 뿐이다 라고 생각한것.
  • 하트 왕과 하트 여왕의 차이점을 과감하게 무시한 채 공통점만을 취해 단순화 해버렸다.

p84

객체는 특정한 개념을 표현하는 일원이 되는데, 객체에 어떤 개념을 적용하는 것이 가능해서 개념 그룹의 일원이 될때 객체를 그 개념의 인스턴스(instance)라고 한다.

주변의 복잡한 객체들은 단지 몇가지 개념의 인스턴스일 뿐이다.

p87

객체를 분류하기 위한 틀

분류란 객체에 특정한 개념을 적용하는 작업이다. 객체에 특정한 개념을 적용하기로 결심했을 때 우리는 그 객체를 특정한 집합의 멤버로 분류하고 있는 것이다.

  • 이러한 분류는 추상화를 위한 도구다. 정원사, 병사, 신하, 왕자, 하객, 왕과 여왕들 모두를 '트럼프'로 묶어서 개별 객체 간의 차이점을 무시하고 공통점을 취한다.
    • 우리가 중요하다고 생각하는 특징은 몸이 납작하고 두 손과 두 발이 네모난 몸 모서리에 달려 있다는 것, 앨리스의 이야기를 풀어나가는데 도움이 되지 않는 것들은 모두 무시하고 있다.
    • 불 필요한 세부사항을 제거한 추상화를 이루었다는 것이다.

p91

  • 데이터 타입은 메모리 안에 저장된 데이터의 종류를 분류하는 데 사용하는 메모리 집합에 관한 메타 데이터다. 데이터에 대한 분류는 암시적으로 어떤 종류의 연산이 해당 데이터에 대해 수행될 수 있는 지를 결정한다.
일반화 / 특수화 관계

p98

  • 객체지향에서 일반화/특수화 관계를 결정하는 것은 객체의 상태를 표현하는 데이터가 아니라 행동이라는 것이다.
    • 어떤 객체가 다른 객체보다 더 일반적인 상태를 표현하거나 더 특수한 상태를 표현한다고 해서 두 객체가 속하는 타입 간에 일반화/특수화 관계가 성립하는 것은 아니다.
    • 두 타입 간에 일반화/특수화 관계가 성립하려면 한 타입이 다른 타입보다 더 특수하게 행동해야 하고 반대로 한 타입은 다른 타입보다 더 일반적으로 행동해야 한다.
  • 객체의 일반화/특수화 관계에 있어서도 중요한 것은 객체가 내부에 보관한 데이터가 아니라 객체가 외부에 제공하는 행동이다.
  • 행동의 관점에서 더 일반적인 타입이라 무엇이고 더 특수한 타입이란 무엇인가?
    • 일반적인 타입이란 특수한 타입이 가진 모든 행동들 중에서 일부 행동만을 가지는 타입을 가리킨다.
    • 특수한 타입이란 일반적인 타입이 가진 모든 행동을 포함하지만 거기에 더해 자신만의 행동을 추가하는 타입을 가리킨다.
  • 따라서 일반적인 타입은 특수한 타입보다 더 적은 수의 행동을 가지고 특수한 타입은 일반적인 타입보다 더 많은 수의 행동을 가진다.

p99

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

  • 서브타입(Subtype) : 특수한 타입

  • 가장 중요한 것은 행위적 호환성이 만족되어야 한다. 슈퍼타입의 서브타입이 될려면 일단 행위가 호환이 되어야 한다.

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

  • 어떤 타입이 다른 타입의 서브타입이라고 말할 수 있으려면 다른 타입을 대체할 수 있어야 한다.[Liskov 1988].

p101

  • 왜 타입을 사용해야 하는가?

    • 인간의 인지 능력으로는 시간에 따라 동적으로 변하는 객체의 복잡성을 극복하기가 너무 어렵기 때문이다.
  • 그래서 결국 타입은 추상화다

    • 타입을 이용하면 객체의 동적인 특성을 추상화할 수 있다.
    • 시간에 따른 객체의 상태 변경이라는 복잡성을 단순화할 수 있는 효과적인 방법이다.

p104

  • 하나의 객체가 특정 시점에 구체적으로 어떤 상태를 가지느냐.

  • 이를 객체의 스냅샷이라고 한다.[D'Souza 1998]

  • 객체지향 모델링을 위한 표준 언어인 UML에서는 객체 다이어그램[Fowler 2003] 이라고도 불린다.

  • 실제로 객체가 살아 움직이는 동안(실행되는 동안) 상태가 어떻게 변하고 어떻게 행동하는지를 포착하는 것을 동적모델 이라고 한다.

  • 객체가 가질 수 있는 모든 상태와 행동을 시간에 독립적으로 표현하는 것을 타입모델[D'Souza 1998] 이라고 한다.

    • 이는 객체가 속한 타입의 정적인 모습을 표현하기 떄문에 정적 모델이라고 한다.
클래스
  • 대부분의 사람들은 클래스와 타입을 같은 것이라고 생각한다.

  • 클래스와 타입을 구분할 수 있을려면 어떻게 해야할까?

  • 클래스와 타입을 구분하는 것은 설계를 유연하게 유지하기 위한 바탕이다.

    • 클래스는 타입의 구현 외에도 코드를 재사용하는 용도로도 사용된다.
    • 객체를 분류하는 기준은 타입이며, 타입을 나누는 기준은 객체가 수행하는 행동이다.
    • 객체를 분류하기 위해 타입을 결정한 후 프로그래밍 언어를 이용해 타입을 구현할 수 있는 한 가지 방법이 클래스이다.
결론
  • 객체지향에서 중요한 것은 동적으로 변하는 객체의 '상태'와 상태를 변경하는 '행위'다.
  • 클래스는 타입을 구현하기 위해 프로그래밍 언어에서 제공하는 구현 메커니즘이다.
2024.11.04