LostCatBox

(리뷰)객체 지향의 사실과 오해 책 리뷰

Word count: 1.2kReading time: 7 min
2023/05/28 20 Share

참조

강추) 책을 삽시다!

훨씬 좋은 내용이 많습니다. 많이 배웠습니다 감사합니다. 저자님

왜?

객체 지향적으로 짠다는 것은 무엇을까? 한번 생각해 보는 시점이 되었다.

어떻게 하면 더 좋은 코드를 짤수있을까?

예를 들면, request.checkValidation() 를 하는것이 좋은것인가?, 아니면, checkValidation(request)의 형태를 만드는 것이 더 객체 지향 스러운것인가? 너무 궁금헀다. => 결과적으론 이 문제는 상황마다 다르다라는 것이 정답이였다.(꼭 객체 지향이 좋은것도아님)

  • 객체의 자율성을 보장한다면, instance.checkValidation()
  • 하지만 여러 객체에서 쓰인다면, Validation 클래스에 뺴고, valid 역할 위임 이 적절할 것이다.

해당 질문에 고려해야할 부분

DTO의 밸리데이션은 비즈니스인가 아닌가, 밸리데이션이 모델들에 대해 공통화가 가능한가?

  • 밸리데이션이 널체크면 비즈니스 아님
  • (비즈니스) 어떤 커맨드만 요청이 가능하다, 어떤 커맨드는 이런 부수정보가 필요하다

하여튼 이제부터 책 리뷰를 써보자

핵심 요약

  1. 책임, 역할, 협력을 항상 생각하자
  2. 메세지가 책임을 결정한다.(설계의 시작점 = 메세지)
  3. 클래스가 아니라 행위, 속성에 대해 생각해보고, 타입(=개념)으로 분류하여, 설계하자
  4. 도메인 모델, 유스케이스 만들자

객체 지향이란?

  1. 클래스가 아니라 객체를 바라보는 것
  2. 객체를 독립적인 존재가 아니라 기능을 구현하기 위해 협력하는 공동체의 존재
  3. 협력에 참여하는 객체들에게 얼마나 적절한 역할과 책임을 부여
  4. 앞에서 설명한 개념들을 프로그래밍 언어라는 틀에 흐트러짐 없이 담아낼 수 있는 기술 활용

큰 목차

  1. 협력하는 객체들의 공동체
  2. 이상한 나라의 객체
  3. 타입과 추상화
  4. 역할, 책임, 협력
  5. 책임과 메시지
  6. 객체 지도
  7. 함께 모으기

협력하는 객체들의 공동체

협력하는 객체들의 공동체

  • 역할: 협력하는 과정 속에 특정한 역할이 존재한다. 책임이나 의무를 의미한다.

  • 책임: 역할에 포함되고, 특정 역할이 정해지면, 특정 책임이 있다.

  • 협력: 요청과 응답을 통해 협력한다.

  • 다른 객체에 요청을 통해 도움을 요청하고 → 받은 객체는 책임을 다해 응답한다!

특정 역할과 적합한 책임에 특징에 관하여

  • 여러 사람이 동일한 역할을 수행할수있다. 손님입장에서 아무 캐시어든 상관없는것처럼(대체가능)

  • 동일한 요청을 받아서 서로 다른 방식으로 응답할 수 있는 능력을 다형성

  • 어떤 객체도 섬이 아니다 → 반드시 협력, 책임, 역할이있다.

  • 객체 지향 설계 == 적절한 객체에게 적절한 책임을 할당하는것이다

  • 역할 == 관련성 높은 책임의 집합이다.

    • 역할은 대체 가능성을 의미한다
    • 각 객체는 책임을 수행하는 방법을 자율적으로 선택(다형성)할수있다.
    • 하나의 객체가 동시에 여러 역할을 수행할 수 있다.
  • 협력의 참여하는 주체는 객체의 특징

    • 객체는 충분히 협력적이여야한다. 모든것을 스스로 처리하는 전지전능한 god object는 복잡도자멸!
    • 객체는 충분히 자율적이여야한다. 자기 스스로의 원칙에 따라 어떤 일을 하거나, 통제하여 절제하는것. 요청 받고 일에 스스로 책임진다. 누구에게 요청을 할지, 자신이 어떤 방식으로 처리할지 누가 정해주지않는다. 자율적으로 일을 판단, 책임진다.
  • 객체는 흔히 상태와 행동을 함께 지닌 실체라고 정의한다. 객체는 조리법을 이미 알고있고, 필요한 상태와 행동을 알고있다.

  • 객체 지향은 데이터와 프로세스를 하나의 객체라는 틀안에 묶어 놓으므로서 객체의 자율성을 보장한다

  • 객체는 메세지로 서로 통신하며, 송신사, 수신자로 구별된다.

  • 수신자는 먼저 수신된 메세지를 이해할 수 있는지 판단후, 미리 정해진 자신의 방법으로 메시지를 처리한다. 이를 메서드라고 부른다. 즉, 객체가 실행 시간에 적절한 메서드를 선택할 수 있다.

  • 메세지와 메서드가 분리된것은 객체의 자율성을 높이며, 캡슐화 개념과 연관이 깊다

객체를 지향하라

  • 객체지향의 핵심은 적절한 책임을 수행하는 역할 간의 유연하고 견고한 협력 관계를 구축하는 것이다. 클래스는 협력에 참여하는 객체를 만드는 데 필요한 구현 메커니즘일 뿐니다.
  • 클래스의 구조와 메서드가 아니라 객체의 역할, 책임, 협력에 집중하자
  • 객체는 행위에 따라 변할 수 있는 상태를 가지고있다

이상한 나라의 객체

  • 객체는 결국 상태(state), 행동(behavior), 식별자(identity)를 갖고있다.
    • 구별될수있고, 상태, 행동을 가진다.
    • 상태를 가진이유는, 행동의 여부가 상태에 의존하기때문이다.(20cm이하만 통과하는 메서드 생각해보자)
  • 앨리스와 객체
    • 객체의 상태를 구성하는 모든 특징들을 통틀어 객체의 프로퍼티라고한다.(일반적으로 프로퍼티는 정적이다) 엘리스의 키, 위치, 음료
    • 반면 프로퍼티(property)의 값은 동적이다 엘리스의 키, 위치, 음료 값은 계속 바뀔수있다.
  • 객체의 프로퍼티는 속성과 링크의 두가지 조합으로 표현된다
    • 객체와 객체 사이의 의미 있는 연결을 링크⇒ 객체의 링크(link)를 통해서만 메세지를 주고받을수있다.
    • 객체가 참조값으로 가진 객체 식별자인 링크와 달리 객체를 구성하는 단순한 값은 속성(attribute) 이다
    • 상태는 특정 시점에 객체가 가지고있는 정보의 집합으로 객체의 구조적 특징을 표현한다.
    • 상태는 객체에 존재하는 정적인 프로퍼티와 동적인 프로퍼티 값으로 구성된다.

은유와 객체

  • 객체의 세상과 지금의 세상은 다르다. 하지만 은유로서 쉽게 사용자를 설득할수있다.
    • 현실세상에서의 메뉴는 자신의 행동을 직접할수없지만, 객체에서의 메뉴는 자율적 행동이 가능하다.

타입과 추상화

추상화를 통한 복잡성 극복

  • 추상화가 되어 같은 타입(=개념)정의 하면, 인간이 쉽게 인지가능하다.
    • 에스프레소, 아메리카노, 라떼 등을 음료수라는 타입으로 정의하면? 공통된 특성과 역할이 한번에 보인다. 또한 추상화된 음료수라는 타입은 단순하고, 빵이라는 타입과는 분류된다.
  • 타입은 개념이다.

타입과 계층

  • 개념

    • 심볼: 개념을 가르키는 간략한 이름
      • 자동차
    • 내연: 개념의 완전한 정의를 나타내며, 내연의 의미를 이용해 객체가 개념에 속하는지 여부 확인가능
      • 바퀴 4개, 이동, -> 자동차
    • 외연: 개념에 속하는 모든 객체의 집합(set)
      • 포르쉐, 람보르기니
  • 분류

    • 분류란 객체에 특정한 개념을 적용하는것, 자동차-> 람보르기니, 포르쉐 등등 포함된다.
    • 어떤 객체를 어떤 개념으로 분류할지가 객체지향의 품질을 결정한다.(유지보수관점, 변경 용이, 정신적인 지도)
    • 결국 추상화를 위한도구다!
    • 구체적인 객체의 공통점만 취하고, 일반화를 하고 단순화한다.
    • 부분을 강조하기 위해불필요한 세부 사항을 제거해 단순화하는것이다.
    • 객체는 복잡하기 떄문에 분류, 개념으로 추상화해야한다.
  • 객체는 행동이 우선이다

    • 객체는 어떤 행동을 하느냐에 따라 객체의 타입이 결정된다
    • 객체의 내부 표현 방식이 다르더라도, 어떤 객체들이 동일하게 행동한다면, 그 객체들은 동일한 타입에 속한다 = 동일한 책임을 수행하는 일련의 객체는 동일한 타입에 속한다
      • 같은 타입은 다른 데이터를 가져도, 행동만 동일하면 된다. 같은 메세지를 받아서 처리할수있는 책임이잇는것이다
      • 다형성 = 동일한 요청에 대해 서로 다른 방식으로 응답할수있는 능력!
    • 외부에 행동만을 제공하고 데이터는 행동 뒤로 감춘다 = 캡슐화
      • 공용 인터페이스 뒤로 데이터를 캡슐화하라!
  • 타입은 개념이다.

    • 타입의 정의는 개념의 정의와 완전히 동일하다. 공통점을 기반으로 객체를 묶는 틀이다.
      • 동일하게, 심볼, 내연, 외연을 이용해 서술하고, 타입에 속하는 객체 역시 타입의 인스턴스라고한다.
  • 일반화와 특수화 관계

    • 특수화 : 탈것 -> 자동차 -> 포르쉐
    • 일반화: 포르쉐 -> 자동차 -> 탈것
  • 슈퍼타입과 서브타입

    • 주의할것은 두 타입간의 관계가 행동에 의해 결정되는것이다. 행위적 호환성 여부
    • 서브타입은 슈퍼타입의 행위와 호환되기 떄문에 서브타입은 슈퍼타입을 대체할수있어야한다
  • 일반화는 추상화를 위한 도구다

정적 모델

  • 타입의 목적
    • 쉽게 인지
    • 시간에 따라 동적으로 변하는 상태의 변화를 동일한 타입으로 인지 가능
    • 엘리스의 키가 100, 30, 40 cm 계속 바뀌는데 동일한 앨리스로 생각한다. (시간에 독립적인 타입)
  • 타입 = 추상화
  • 동적 모델과 정적 모델
  • 클래스 (타입을 구현하는 가장 보편적인 방법)

책임의 분류

  • 객체의 책임은 하는것과 아는것 로 구성된다. -> 공용 인터페이스로 구성가능 -> 캡슐화

역할 , 책임, 협력

협력

  • 서로가 필요할 때, 요청 응답을 하며, 책임을 다하는 전체모습

책임

  • 메세지가 정해지면, 메세지를 처리할 적절한 객체에게 책임을 부여한다.

역할

  • 같은 역할을 하는 객체들을 서로 대체가 가능하다.
    • 판사, 피고인, 피의자 의 역할이 있다면, 어떤 판사, 피고인, 피의자를 대려다 놓아도 똑같이 법정이 돌아가게된다.

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

객체지향 설계 기법

책임과 메세지

자율적인 책임

  • 재판하라 -> 증언하라는 자율적이다
  • 재판하라 -> 목격장면을 떠올려라 , 떠오르는 기억을 말해라, 말로 간결하게 표현하라 3가지를 같은 객체에게 물어보는건 자율적이지않다
  • 증인은 증언할 책임이있는거지, 구체적인 방법과 절차는 자유다.
  • 어떻게 가 아니라 무엇을 해야하는지 설명하는 것이 책임

메세지와 메서드

메세지를 따라라

  • 메세지에는 무엇이 나온다.
  • 메세지는 송신자와 수신자를 약하게 연결하게한다. -> 유연하고, 확장 가능하고, 재사용가능하게한다
  • 메세지에서 What, Who를 적절히 선택한다. 무엇을 누가 처리할지!!! 설계하자
    • 수신자가 잘 처리할것이라고 믿자.객체는 다른 객체의 상태를 묻지 말아야한다. 자율성 보장
    • 상태를 묻지말고, 시켜라

객체 인터페이스

  • 메세지가 인터페이스를 결정한다.
  • 인터페이스는 객체가 수신할 수있는 메세지의 목록이다.

인터페이스와 구현의 분리(반드시)

  • 추상적인 인터페이스(=자율적인 책임을 보장하라(증언하라 끝!))
  • 최소 인터페이스(외부에서 필요없으면 노출 하지마라)
  • 인터페이스와 구현간 분리하기(=캡슐화)

책임의 자율성이 협력의 품질을 결정한다

객체 지도

기능 설계 VS 구조 설계

도메인 모델(안정적인 구조)

  • 사용자가 프로그램을 사용하는 대상 분야를 도메인이라고한다
  • 도메인 모델이란 사용자가 프로그램을 사용하는 대상 영역에 관한 지식을 선택적으로 단순화하고 의식적으로 구조화한 형태다. 개념간의 관계, 규칙 제약 을 추상화
  • 최종 제품은 사용자의 관점을 반영해야한다. 도메인 모델은 사용자들이 도메인을 바라보는 관점이며 설계자가 시스템의 구조를 바라보는 관점, 코드 모습 그자체 모두 일치화시키자

유스케이스(불안정한 기능)

  • 기능은 항상 확장성을 가지고 있다
  • 사용자들의 목표를 중심으로 시스템의 기능적인 요구사항을 이야기 형식으로 묶을수있다.(시나리오)
  • 유스케이스는 여러 시나리오의 집합이다.
  • 유스케이스는 단순한 기능 목록과 다르다
  • 유스케이스는 사용자 인터페이스와 관련된 세부 정보를 포함하면안되고, 본직적인 유스케이스만 기록한다
  • 유스케이스는 내부 설계와 관련된 정보를 포함하지않는다.

기능 변경흡수가능한 구조(도메인 모델 + 유스케이스)

  • 도메인 모델과 유스케이스를 반드시 작성하자

함께 모으기

  • 개념관점(도메인 모델) -> 명세관점(인터페이스 무엇?) -> 구현관점(어떻게? 클래스, 메서드 추가)
  • 도메인 설정 -> 설계하고 구현하기 -> 코드와 세 가지 관점 -> 끝!
    • 도메인을 설정
    • 필요한 메세지들을 정함
    • 메세지를 처리할 적절한 객체를 찾아 책임 부여
    • 이를 인터페이스로 추상화
    • 구현제에서 어떻게 처리할건지 구체화
CATALOG
  1. 1. 참조
  2. 2. 왜?
  3. 3. 핵심 요약
  4. 4. 객체 지향이란?
  5. 5. 큰 목차
  6. 6. 협력하는 객체들의 공동체
  7. 7. 이상한 나라의 객체
  8. 8. 타입과 추상화
  9. 9. 역할 , 책임, 협력
  10. 10. 책임과 메세지
  11. 11. 객체 지도
  12. 12. 함께 모으기