GRASP(General Responsibility Assignment Software Pattern)
크레이그 라만의 Applying UML and Patterns이라는 책에서 나온 책임 할당을 위한 패턴
각 패턴마다 Solution과 Problem로 구성되어 있다.
정보 전문가 패턴(Information Expert)
Q: 객체에 책임을 할당하는 기본 원칙은 무엇인가?
A: 책임을 수행하는 데 필요한 정보를 가진 클래스(정보 전문가)에게 책임을 할당한다.
정보와 행동을 가까운 곳에 위치시키기 때문에 캡슐화를 유지할 수 있다.
필요한 정보를 가진 객체들로 책임이 분산된다.
창조자 패턴(Creator)
Q: 누가 객체 A를 생성하는가?
A: 다음의 조건을 최대한 많이 만족하는 객체에게 객체 생성 책임을 할당해야 한다.
- B가 A 객체를 포함 또는 참조한다.
- B가 A 객체를 기록한다.
- B가 A 객체를 긴밀하게 사용한다.
- B가 A 객체의 초기값을 가지고 있다.
생성 예정인 객체와 연관되어 있는 객체가 생성 책임을 가지고 있게 된다면, 이미 해당 객체와 결합되어있다고 생각할 수 있다. 따라서 전체적인 결합도를 낮게 유지할 수 있다.
낮은 결합도 패턴(Low Coupling)
Q: 의존성을 낮추고 변화의 영향을 줄이며 재사용성을 증가시키는 방법은?
A: 전체적인 결합이 낮게 유지되도록 책임을 할당해야 한다.
결합도(Coupling) 객체 사이의 의존성이 과한 경우 결합도가 높다고 말한다.
- 오브젝트 p.17
결합도를 낮춘다면 다음과 같은 이점이 있다.
- 다른 구성 요소의 변화에 영향을 받지 않는다.
- 재사용이 편리해진다.
- 해당 클래스에 대한 이해가 쉬워진 다. (의존하는 클래스가 적기 때문에)
높은 응집도 패턴(High Cohesion)
Q. 객체를 관리하기 쉽게 하려면 어떻게 해야 할까?
A. 높은 응집도를 유지할 수 있게 책임을 할당해야 한다.
응집도(Cohesion) 연관된 작업만을 수행하고 연관성 없는 작업은 다른 객체에게 위임하는 객체를 가리켜 응집도가 높다고 말한다.
- 오브젝트 p.26
변경의 이유에 따라 클래스를 분리한다면 응집도를 높일 수 있고, 응집도가 높아진다면 다음과 같은 이점이 있다.
- 해당 클래스에 대한 이해가 쉬워진다. (할당된 책임만을 수행하고 있기 때문에)
- 유지보수가 쉬워진다.
- 낮은 결합도 또한 지원한다.
- 응집도가 높은 클래스는 특정한 목적에 사용할 수 있기 때문에 재사용하기 좋다.
컨트롤러 패턴(Controller)
Q. 사용자의 요청을 처리하는 것은 누가 담당해야 하는가?
A. 사용자의 요청을 처리하는 Controller 객체를 만들어서 사용해야 한다.
어떤 서브시스템이 존재한다고 가정할 때
- 직접적으로 객체에 접근하여 프로그램을 사용한다면 결합도가 상승한다.
- 서브 시스템에 들어오는 요 청을 처리해주는 컨트롤러가 있다면 사용하는 입장에서는 해당 컨트롤러만 알면 된다.
- 만약 서브 시스템의 변경이 생겼을 때 외부에 미치는 영향도 줄어든다.
다형성 패턴(Polymorphism)
Q. 객체의 타입에 따라 행동이 바뀐다면 책임을 어떻게 할당해야 할까?
A. OOP가 지원하는 다형성을 적극적으로 활용한다. (인터페이스를 두고 행동에 대한 부분을 구현)
객체의 종류에 따라 분기하는 조건문이 아닌 다형성을 사용하는 것이 좋은 방법이다.
새로운 타입이 추가되었을 때 조건문을 사용한다면 기존의 조건문을 수정해야 하지만 다형성을 활용하면 쉽게 확장할 수 있다.
변경 보호 패턴(Protected Variations)
Q. 어떻게 하면 변경이 다른 요소에 영향을 미치지 않도록 방지할 수 있을까?
A. 변화가 예상되는 지점을 식별하고, 주위에 안정된 인터페이스를 형성하도록 책임을 할당해야 한다.
간접 참조 패턴(Indirection)
Q. 두 객체 사이의 직접적인 연결을 피하고 싶다면 어떻게 해야 할까?
A. 두 객체 사이에 또 다른 객체를 두어 직접적인 연결을 피할 수 있다.
중재자 패턴을 사용하여 두 객체 사이에 또 하나의 객체를 추가하여 복잡한 관계를 단순화할 수 있다.
중간에 인터페이스를 둔다면 변경 보호 패턴(Protected Variations)에 해당된다.
순수한 가공물 패턴(Pure Fabrication)
Q. 책임을 할당한 도메인 객체가 Low Coupling, High Cohesion, 재사용성 등의 목적을 위반한다면 어떻게 해야 할까?
A. 도메인 개념을 포함하지 않는 클래스를 하나 만들고 매우 응집된 책임을 할당할 수 있다.
행동을 추가할 때, 해당 책임을 수행할 도메인 개념이 존재하지 않는다면 도메인과 무관한 인공적인 객체를 만든다음 해당 객체에게 책임을 할당한다.
객체가 데이터베이스에 저장해야 할 값을 가지고 있다고, 정보 전문가 패턴을 적용하여 데이터베이스에 저장하라는 책임을 가지라고 하지 않는다.
예) 상점과 고객 클래스가 있고 서로 다른 통화를 사용하고 있다고 가정
- 서로 다른 통화를 사용하고 있기 때문에 거래를 하려면 환전을 해야한다.
- 두 클래스 다 환전에 대한 책임을 부여하기 애매하다면 환전을 책임하는 클래스를 추가하고 사용할 수 있다.
참고 자료
오브젝트 5장. 책임 할당하기, 조영호
Applying UML and Patterns Chapter 16, Chapter 21 GRASP, Craig Larman