오브젝트 -5

송은우·2022년 10월 7일
0

TIL

목록 보기
24/61

GRASP 패턴. 책임 할당의 어려움을 도와줌
응집도, 결합도, 캡슐화 같은 다양한 기준으로 책임을 할당하고, 결과를 트레이드오프할 기준을 알 수 있다.

  1. 행동을 먼저 해라
  2. 협력이라는 문제의 책임을 결정해라

협력을 시작하는 주체는 메시지 전송자. 따라서 적합한 책임이란 전송자에게 적합한 책임이다.
클라이언트의 의도에 적합한 책임을 할당해야 한다.

클라이언트의 관점에서 객체가 수행하는 행동이란 객체의 책임이다.
책임 => 필요한 데이터 순으로 설계해야 한다

메시지는 책임을 어떻게 식별해야 하는가에 대한 책임을 결정한다.
메시지를 결정한 이후에 객체를 선택해야 한다.
1. 메세지를 전송해야 하는데, 누구에게 보내야 하지?
메시지는 클라이언트의 의도를 갖는다.
자신의 의도를 담은 무언가 메시지를 보내면 이걸로 역할은 종료된다
책임과 협력관계가 정리되기 전까지 내부 상태에 관심을 가지지 않는다

GRASP패턴
도메인 개념에서 출발. 관게를 그냥 표현함
책임을 할당받을만한 객체들의 존재, 관계들을 그냥 표현함
정보 전문가에게 책임을 할당한다
메시지를 전송할 객체는 무엇을 원하는가
메시지를 수신할 적합한 객체는 누구인가?
INFORMATION EXPERT 패턴 정보 전무가가 책임을 ㄱ자는다
자신이 소유하는 정보와 관련된 작업을 한다
정보!=데이터 알고있다!= 저장해야 한다
그냥 정보를 제공 받아버릴 수 있다.

설계는 트레이드오프의 과정이다.
동일한 기능을 구현할 수 있는 설계는 무수히 많다
Low Coupling High Cohension. 이미 알고 있는 정보가 있다면, 그걸로 계산하고, 모르는 객체에게 알게할 필요가 없다
creator 패턴
아래 조건을 최대한 많이 가지고 있을 객체에게 생성의 역할을 넘긴다
1. B가 A를 포함하거나 참조한다
2. B가 A를 기록한다
3. B가 A를 긴밀하게 사용한다
4. B가 A를 초기화 하는데 필요한 데이터를 가지고 있다.(정보 전문가이다)
구현을 통한 검증

변경의 이유에 따라 클래스를 분리해야 한다.
코드를 토앻변경의 이유를 파악할 수 있는 첫번째 방법은, 인스턴스 변수가 초기화 되는 시점을 보면 된다. 함께 초기화 되는 속성을 기준으로 코드를 분리해야 한다

메서드들이 인스턴스 변수를 사용하는 방식을 살펴보는 것이다.

DiscountCondition 타입을 보면enum으로 되어있고, if else를 계속 가져가는데, 이것은 응집도의 기준에서는 안좋은 코드다. 따라서 이를 분리해야 한다.
속성그룹과 해당 그룹에 접근하는 메시드 그룹에 접근하는 메서드 그룹을 기준으로 코드를 분리해야 한다.

응집도 판단 기준
1. 클래스가 하나 이상의 이유로 변경해야 한다면 응집도가 낮은 것이다.
2. 클래스의 인스턴스가 초기화 되는 시점의 경우에 서로 다른 속성들을 초기화 하고 있다면, 응집도가 낮은 것이다. 초기화 되는 그룹을 기준으로 클래스를 분리하여라
3. 메서드 그룹이 속성 그룹을 사용하는지 여부로 나눌 수 있다면 응집도가 낮은 것이다. 이를 분리해라

이를 분리한다면, 문제가 또 생긴다. 원래는 하나의 클래스만 있으면 됐는데, 조건이 필요한 수많은 클래스들을 다 알아야 하니 결합도가 올라간다

이를 또 다시 다형성을 이용해서 모으게 된다면 훨씬 효과적이 된다.
interface를 통해서 추상화를 하고, 구현을 공용화 하게 된다면 훨씬 좋은 품질의 콛그ㅏ 나올 수 있다.
객체의 타입에 따라 변하는 행동이 있다면 타입을 분리하고, 변화하는 행동을 각 타입의 책임으로 할당하라는 것이다. 이를 POLYMORPHISM 이라고 한다.
변경을 캡슐화 하도록 책임을 할당하는 것은 GRASP 에서 PROTECTED VARIABLE패턴이라고 부른다
변화의 불안정성이 나올 것같은 부분에서 인터페이스르 통해 관리할 수 있도록 책임을 만들어야 한다. Protected variable 패턴은 책임 할당의 관점에서 캡슐화를 설명한 것이다.
예측 가능한 변경으로 인해 여러 클래스들이 불안정해진다면 인터페이스로 변환 후 캡슐화 한다.

변경 역시 도메인 모델의 일부이다. 도메인 모델은 단순히 설계에 필요한 용어를 제공하는 것을 넘어 코드의 구조에도 영향을 미친다. 도메인 모델에는 도메인 안에서 변하는 이들 사이에 대한 관계가 투영되어있어야 한다. 구현을 가이드 할 수 있는 도메인 모델을 선택해야 한다.
도메인의 구조가 코드의 구조를 이끌어 내는 것은 자연스러울 분만 아니라, 바람직한 것이다.

변경에 대비하는 방법 2가지
1. 코드를 이해하고 수정하기 쉽게 단순하게 설계하는 것
2. 코드를 수정할 필요 없이 유연하게 설계하는 것
대부분은 전자가 좋다. 많이 바뀐다면 후자가 좋다

코드가 도메인의 구조에 대한 새로운 통찰력을 제공한다.
너무 특수한 방법이 구체적으로 코드에 들어났다면 수정해야 할 필요가 있을 가능성이 높다.

일단 절차지향으로 대충 짜고, 객체지향으로 옮기는 것도 좋다.
코드를 수정한 이후에 겉으로 드러나는 동작이 바뀌어서는 안된다. 캡슐화를 향상시키고, 응집도를 높이고, 결합도를 낮추어야 하지만, 동작은 그대로 유지해야 한다.
이해하기 쉽고 수정하기 쉬운 소픝웨어로 개선하기 위해 겉으로 보이는 동작을 수정하지 않고, 내부 구조를 수정하는 것을 리팩토링이라고 한다. 객체 디자인에서 가장 기본이 되는 것 중의 하나는 책임을 어디에 둘지 결정하는 것이다. 처음에는 당연히 어렵지만, 리팩토링을 통해서 한다면 더 좋은 결과가 나올 수 있다.

너무 긴 메서드는 수행하는 것을 한 눈에 보기 얿고, 전체적으로 이해하는데 시간이 오래걸린다
하나의 메서드 안에 다양한 작업을 하기에, 변경이 필요할 때 수정해야 할 부분을 찾기 어렵다
나머지 부분에서 버그가 날 수 있다.
일부만 재사용이 불가능하다
중복을 초래하기 쉽다.

몬스터 메서드라고 긴 메서드를 칭한다.

주석 추가 대신 메서드를 작게 분리해라

애플리케이션은 클래스의 집합이 아니다. 클래스는 구현 도구일 뿐이다.

profile
학생의 마음가짐으로 최선을 다하자

0개의 댓글