본문 바로가기
OOP/<오브젝트>, 조영호

5장 책임 할당 GRASP 패턴

by 민휘 2024. 1. 17.

5장 관련 이야기 나눈 내용

  • 리팩터링 이야기. 스프링을 처음 배우고 나서 만든 스프링 프로젝트의 코드를 열어보니 너무 더럽더라. 그래서 리팩터링을 시도했는데, 이미 코드가 많은 상태에서 개선하려고 하니 너무 강하게 결합되어서 조금만 고쳐도 컴파일 오류가 났다. 결국 코드를 새로 작성하는 것밖에는 답이 없겠다 싶었다. 너무 큰 작업이라고 생각해 지금도 미루고 안 하고 있다. ㅋㅋㅋㅋ 어쨌든 리팩토링은 코드가 조금 쌓였을 때 주기적으로 하는게 좋은 것 같다. (기술부채 상환이라고 하는 듯)
  • 리액트 프로젝트 했을 때 코드를 혼자 쓰는거라 완전 Stateful(?)하게 의존성 높게 짰다. 후반에 시간이 모자라서 협업을 하게 됐는데 다른 사람에게 코드를 이해시키느라 시간이 더 오래 걸렸을 정도로 코드가 복잡했다. 원래 컴포넌트 주도 설계를 해야 한다고 하심. (이게 안드 컴포즈나 플러터 위젯인가?)
  • 클린코드나 디자인 패턴에서 제시하는 도구들을 어떻게 사용해야할지, 이게 왜 중요한지 와닿기 시작했음. 객체지향이라는 전체적인 맥락에서 효과적인 도구였던 것임. 이걸 왜 쓰는지, 어디부터 잘못 된건지 알아야지, 단순히 코드가 이런 신호를 보였을 때 이렇게 고쳐라를 반사적으로 수행하는건 일시적인 해결방법일 수 있음. 물론 이런 접근으로 설계의 개선을 시작하는 것만으로도 의미가 있다고 생각함.

 

설계의 무게중심을 행동으로 옮기는 접근 방법

  • 메시지부터 결정한다 : 송신자는 수신자에 대해 어떠한 가정도 할 수 없으므로 수신자가 깔끔하게 캡슐화된다. 메시지가 존재하므로 객체가 필요한 것이다.
  • 협력 문맥에서 책임을 결정한다 : 책임은 객체가 참여하는 협력에 적합해야 한다.

 

도메인 개념 활용하기

  • 도메인 개념을 책임 할당 대상으로 사용한다.
  • 도메인 모델의 개념의 의미와 관계가 완벽할 필요 없다. 책임 할당 받을 객체의 종류와 관계에 대해 유용한 정보를 제공할 수 있다면 충분하다.
  • 코드를 구현하여 얻는 통찰이 역으로 도메인을 바꿀 수 있다.

 

정보 전문가 패턴

  • 애플리케이션이 수행해야하는 기능에서 첫 메시지를 추출한다.
  • 책임을 수행하는데 필요한 정보를 알고 있는 도메인 후보에 객체 형태로 책임을 할당한다.
  • 객체의 내부 구현을 고민한다. 이때 스스로 처리 불가능한 작업이 있으면 새 메시지를 추출하고, 첫 단계를 반복한다.
  • 상태와 행동을 같이 가지는 자율성 높은 객체를 설계할 수 있다.

 

낮은 결합도 & 높은 응집도 패턴

  • 책임을 할당할 수 있는 다양한 대안이 있으면 응집도가 높고 결합도가 낮은 대안을 선택하라
  • 결합도가 낮은 방법 : 이미 결합된 객체와 상호작용
  • 응집도가 높은 방법 : 의존성을 추가했을 때 객체의 책임이 추가되는지 확인

 

생성자 패턴

  • 객체를 생성하는 책임을 누구에게 할당할 것인가?
  • 이미 결합된 객체에게 생성 책임을 할당한다. 시스템의 전체적인 결합도는 증가하지 않는다.

 

다형성 도입을 위한 설계 개선 작업

  • 변경 이유가 하나 이상이다 → 변경 이유를 기준으로 클래스를 분리하고, 추상적인 책임을 만들기 위해 역할을 도입한다.
  • 생성자에서 모든 속성이 함께 초기화되지 않음. 즉, 지연 초기화가 일어난다. → 생성자에서 모든 속성이 함께 초기화되도록 분리하여 응집도를 높인다.
  • 메소드 내에서 일부 필드만 참조함. → 메소드가 모든 필드를 사용하도록 쪼갠다.

 

리팩터링

  • 데이터 중심으로 우선 빠르게 구현한다.
  • 메소드를 작게 쪼갠다. 작고, 응집도가 높고, 재사용 가능하다.
  • 메소드가 사용하는 데이터를 저장한 (결합된) 클래스로 메소드를 이동하고, 접근제어자와 의존성을 수정한다.
  • 다형성과 변경 캡슐화를 적용하여 서브 타입을 만든다.
  • 코드를 변경하더라도 기능은 동일하게 수행한다.