오브젝트 Object 요약 3~5

Mr_Gu·2022년 1월 16일
0

books

목록 보기
4/8
post-thumbnail

3. 역할, 책임, 협력

  • 객체 지향 설계의 핵심은 객체들에게 적절한 책임을 부여하고 각각의 객체는 협력이 부여한 역할을 수행하며 시스템의 목표를 달성하는 구조를 만드는 것이다. 다형성, 상속, 합성, 추상화 등등의 기법은 이를 위한 방법들 중 하나이다.

협력

메시지를 이용해서 객체끼리 통신하면서 이루어지는 활동
협력에 참여하는 객체는 자신이 아는 정보에 관한 행동은 자기가 해야 한다.(자율성)
협력이 객체에게 책임을 부여하기 위한 문맥을 제공한다.

책임 할당하기

객체의 책임은 결국 협력에 따라 달라진다.
협력은 메시지를 통해 이루어지므로 객체를 선정하기 전에 메시지를 먼저 생각하자.
메시지 => 해당 메시지를 받을 객체 => 메시지 => ....

책임 주도 설계
전체 시스템 책임(시스템의 기능) 파악이 최우선이다.
시스템 책임을 더 작은 책임으로 분할한다.
분할된 책임을 수행할 수 있는 적절한 객체 또는 역할을 찾아 책임을 할당한다.
책임 수행 중 다른 객체의 도움이 필요한 경우 이를 메시지로 만들고 이를 책임질 객체를 만든다.
이 과정을 계속한다.

  • 메시지가 객체를 결정한다.
  • 행동이 상태를 결정한다.

역할

협력 관계에서 객체를 갈아끼울 수 있는 슬롯이다.

위의 예제에서 DiscountPolicy가 역할이고 그 밑에 객체들로 갈아 끼울 수 있다.
역할은 책임의 추상화, 책임들의 집합이다. 다만 역할과 책임이 일대일인 경우도 많기 때문에(굳이 역할로 추상화 할 필요가 없는 경우도 많다.) 처음부터 역할을 의식하지 말자.

협력(collaboration) => 역할(role) => 객체(object) => 클래스(class)


4. 설계 품질과 트레이드오프

설계의 적합성 판단하기

  1. 캡슐화 : 변경될 가능성이 높은 부분이 잘 숨겨져 있는지
  2. 낮은 응집도 : 요구사항 변경 시(책임 변경) 얼마나 많은 객체를 수정해야 할까.
    하나의 목표를 수행하고 있는지에 관한 관점.
  3. 높은 결합도 : 특정 객체가 변할 시 얼마나 많은 객체를 수정해야 할까.
    얼마나 많은 객체와 연관되어 있는지에 관한 관점

데이터 중심 설계

객체에 들어갈 데이터 => 메서드 => 협력 순으로 이루어짐.
예제 코드 보면 알겠지만 정말 복잡해진다...

문제점!

  1. 캡슐화 실패 : 접근 제어자를 쓴다고 캡슐화 했다 생각하지 말자. 외부 객체에게 정보를 주지 말아야 숨긴거다.
  2. 낮은 응집도 : 할인 정책 추가한다면 얼마나 많은 객체를 고쳐야 할까...
  3. 높은 결합도 : DiscountCondition이 변한다면 얼마나 많은 객체를...
  • 스스로 자신의 데이터를 책임저라. 객체가 자율적으로 활동할 수 있도록 코드 배치를 변경하였다.

그래도...

DiscountPolicy를 쓸려면 type을 알고 있어야 한다. 이게 캡슐화 측면에서는 DiscountPolicy에 관한 정보가 노출된 셈이고 type으로 빼면서 정책 추가나 변경시 if else문을 건들여야 한다.

  • 데이터를 먼저 생각하니깐 협력에 필요한 행동보단 데이터에 제한된 행동만을 생각하게 된다. (자율성 훼손), 그리고 데이터는 숨겨져야 하는 부분이지만 데이터 위주로 생각하다보니 public interface에 데이터에 관한 정보가 세어나오기 쉽다.(무분별한 getter와 setter)

05. 책임 할당하기

핵심은 협력이란 문맥 안에 책임 결정하기(책임 주도 설계), 데이터보다 행동 먼저 결정하기다. 그러나 이는 꽤나 추상적인 조언이기에 좀더 구체적인 GRASP 패턴을 소개하도록 하겠다.

GRASP 패턴

General Responsibility Assignment Software Pattern (일반적인 책임 할당을 위한 소프트웨어 패턴)

책에서는 책 내용 설명에 GRASP 패턴을 첨가하는 방식으로 진행하였다. 그래서 책 내용 기준으로 정리하되 GRASP 패턴인 부분은 따로 표시하겠다.

1. 도메인 개념에서 출발하기

도메인 개념들을 이용한다면 책임 할당 과정을 시작하기 수월해질 것이다. 다만 도메인 개념을 명확히 정하려 노력할 필요는 없다. 설계를 시작하기 위해 참고하는 용도로 쓰이는게 베스트다.

2. 정보 전문가에게 책임을 할당하라

Information Expert Pattern
특정 책임을 할당할 때 해당 책임에 대해 잘 아는 정보 전문가 객체에게 할당해야 한다.

3. 높은 응집도 낮은 결합도

책임을 할당하다 보면 여러가지 형태의 협력 네트워크가 형성될 것이다. 이들 간의 우열을 가릴 때 결합도와 응집도는 유용한 지표가 될 수 있다.

Low Coupling, High Cohesion
낮은 결합도와 높은 응집도를 가지기 위해 노력하라.

4. 창조자에게 객체 생성 책임을 할당하라.

특정 클래스의 객체를 생성하기 위해서는 해당 객체와 관련된 정보를 어느정도 알고 있어야 한다. 즉 생성 또한 정보를 알아야 하는 행위이기 때문에 해당 객체에 대한 의존성이 생긴다.

Create Pattern
B 객체가 A 객체를 생성한다면...
1. B객체는 A 객체를 포함하거나 참조한다.
2. B객체가 A 객체를 기록한다.
3. B객체가 A 객체를 긴밀하게 사용한다.
4. B객체가 A에 대한 정보 전문가다.

Pure Fabrication
정보 전문가에게 책임을 할당했더니 High Cohesion, Low Coupling을 위반한다면 특정 책임을 몰아줄 인위적인 인공물 객체를 만들자. 생성과 관련된 책임을 맡는 factory object도 pure Fabrication중 하나이다.

5. 다형성을 통해 분리하기

우선 특정 객체를 분리하기 위해서는 해당 객체가 응집성이 낮다는 것을 느껴야 한다. 이를 느끼기 쉽지 않으니 코드 상으로 드러나는 특징을 잘 보도록 하자.
1) 객체 내 맴버 변수의 초기화 시점이 다르다.
2) 멤버 메서드가 멤버 변수의 일부분만 활용한다.

분리될 때 분리된 객체 각각이 협력의 특정 책임에 대응되어서 협력을 여러 개로 표현해야 한다면 이들을 역할로 묶어버리자.

Polymorphism Pattern
협력 내에서 비슷한 책임을 수행하는 객체들은 다형성을 이용해 코딩하라. 특히 코드 내에 type 변수 + if else 콜라보가 있다면 당장 분리해서 다형성을 이용하자.

6. 변경으로부터 보호하기

Protected Variable Pattern
변화가 다른 곳으로 전이되는 곳에 인터페이스를 이용해서 감싸라

그외..

Controller
UI 입력 받아 처리하는 부분은 컨트롤러가 담당하게 하자.

Indirection
두 개의 객체 사이의 결합도를 낮추기 위해 중간 객체를 만들자.

객체 지향 프로그래밍의 대안

  • 일단 절차 지향적으로 짜고 객체 지향적으로 바꾸는 것도 크게 도움된다.
  1. Monster Method => 이름만 봐도 알 수 있는 여러 method로 쪼개자.
  2. 객체를 자율적으로 만들기 + Polymorphism + Protected Variable Pattern

상속과 합성

10장 11장 요약서 제대로 배우자... 요약하자면
Movie + 할인 조건인 서브 클래스 만들기는 이해하기는 쉽지만 유연하지 못하다.
Movie에 할인 조건 객체를 맴버 변수로 가지게 하는 방법은 이해하긴 어렵지만 유연하다.




참고 사이트
GRASP 패턴 : https://m.blog.naver.com/PostView.naver?isHttpsRedirect=true&blogId=kbh3983&logNo=220778008888

profile
그냥... 즐기자..

0개의 댓글