1장 - 전략패턴
요구사항 : 오리 시뮬레이션 게임 SimUduck
- 오리 시뮬레이션 게임
- 이 게임에는 헤엄도 치고 꽥꽤 소리도 내는 다양한 오리가 등장
- 추후 요구사항이 변경되어 날 수 있는 기능이 추가되어야 함
- 또 다른 요구사항으로 소리를 내지 못하는 오리라던지, 날지 못하는 오리 등이 추가 됨
문제를 명확하게 파악하기
- 달라지는 부분을 찾아서 영향을 주이 않도록 캡슐화 한다.
- 바뀌는 부분과 그렇지 않은 부분 분리하기
해결 방법 1 : 상속(슈퍼클래스)을 통한 해결
클래스 다이어그램
요구사항이 추가되기 전 클래스 다이어그램
요구사항 변경으로 인해 추가된 클래스 다이어그램
모든 오리가 꽥꽥 소리를 내고, 헤엄칠 수 있다 생각하여 이런 특성을 모두 슈퍼클래스에서 구현
해당 슈퍼클래스를 상속받은 서브클래스들은 고유한 모양을 나타내는 display메소드를 오버라이딩 해서 자신만의 특성을 만들어 낸다.
장점
- 단순한 요구사항 변경에 발빠르게 대응이 가능함
- 코드의 중복이 줄어들음 (코드의 재사용성 증가)
단점
- 모든 서브클래스가 슈퍼클래스의 메소드를 따르지 않는 예외가 있을 경우 메소드를 오버라이딩 해야만 한다.
- 슈퍼클래스에 의존하는 서브클래스는 점점더 증가할 것이고, 이후 요구사항이 변동될 시 슈퍼클래스의 수정은 곧 서브클래스의 변동을 의미한다.
- 즉 한번의 수정이 너무나도 많은 소스에 영향을 미치게 된다.
- 또한 원치않는 요구사항을 가진 서브클래스의 경우 지속적으로 의미없는 오버라이딩을 하게 된다.
해결 방법 2 : 인터페이스 분리하여 구현
클래스 다이어그램
인터페이스 분리를 진행한 클래스 다이어그램
공통으로 가지는 행동은 슈퍼클래스로, 부분적으로 가지는 행동은 인터페이스로 분리하여 구현
장점
- Flyable, Quackable 인터페이스를 통해서 특정한 행동만 구현할 수 있음
단점
- 같은 행동을 하는 코드가 중복됨
- 날수있는 오리 중에서도 날아다니는 방식이 서로 다를 수 있는 문제가 있음
해결 방법 3 : 분리된 인터페이스 구현체를 따로 구분
행동을 캡슐화해 구현한 인터페이스와 구현체들
A.K.A. 전략패턴
장점
- 오리들이 직접 인터페이스를 구현하지 않기 때문에 코드 중복을 걱정할 필요가 없음
- 새로운 요구사항이 추가되면 인터페이스 구현체를 늘려주면 해결 됨
- 런타임 도중 동적으로 오리의 행동을 바꿀 수 있음
- 직정 정의한 메소드를 쓰는것이 아닌 다른 클래스에 행동을 위임함
public abstract class Duck {
// 직접 구현이 아닌 Setter 혹은 생성자를 통해서 DI 받음
QuackBehavior quackBehavior;
...
public void performQuack() {
// 참조 객체에 행동을 위임함
quackBehavior.quack();
}
}
정리
- 상속을 통한 해결은 지속적 요구사항 해결 해결에 어려움을 가진다.
- 단순히 인터페이스를 분리하여 개별적으로 구현하는것은 코드 중복과 유지보수에 불편함을 가진다.
- 전략패턴을 사용한다면 행동을 외부로 위임하여 코드 중복 문제를 해결하고, 때에따라 유연하게 행동을 변경할 수 있다.
'CS 지식 공부방 > 디자인패턴' 카테고리의 다른 글
[헤드퍼스트 디자인패턴 2장] 옵저버 패턴 (0) | 2022.06.15 |
---|