객체지향 설계를 하며, 아래와 같이 fly()메서드를 Duck 추상클래스에 선언해주고,
매 번 concrete class에서 override하며 정의해준다면,
- 1. 서브클래스에서 코드가 중복됨 ( 같은 fly()형태를 띠는 클래스들에 같은 코드를 중복해서 작성해야함 )
- 2. 실행 시에 특징을 바꾸기 힘들다 ( 클래스 내부에 concrete하게 구현되므로 실행 중 행동의 특성을 바꿀 수 없다)
- 3. 모든 subclass들이 fly()에 관하여 어떤 행동들을 하는지 다 알기 힘들다. ( 관리하기 어려움 )
# 이런 경우에는 fly()를 superClass에서 빼, Flyable 이라는 Interface를 만들어 각 Subclass가 Implement하게 한다면?
=> 해당 특성 (fly, quack)을 갖지 않을 subclass에 구현하지 않을 수 있다는 점은 개선됨
==> But, 코드의 재사용은 하지 못하고, 모든 subclass에 중복적으로 구현해야하는 단점은 그대로
# 여기에 디자인 원칙을 적용해보자
- 디자인 원칙2 : 구현보다는 인터페이스에 맞춰 프로그래밍 한다.
- 디자인 원칙3 : 상속보다는 composition을 사용한다.
아래와 같이, subclass마다 달라지는 부분인 FlyBehavior와 QuackBehavior를 Interface로 구성하고,
각 행동마다의 class 집합을 구성한다.
아래처럼 Duck 의 서브클래스에서는, 각 서브클래스에 맞는 행동 클래스 Object 를 생성하여 superclass에 선언해놓은 인터페이스 타입이 가리키도록 한다.
이렇게 Duck 클래스에
- 인터페이스 형식의 레퍼런스 변수 2개를 선언( object composition )
- 행동은 행동 클래스에 위임 (delegation)
==> 이것이 전략 패턴이며, 많은 디자인 패턴이 전략패턴에 기인한다.
{abstract} Duck 클래스 다이어그램을 확인해보면, setFlyBehavior(), set~~ 메서드들을 확인할 수 있다.
이는 실행 중 동적으로 Duck의 subclass 인스턴스들이 행동 관련 클래스를 갈아끼울 수 있게 하기 위함.
1. 변하는 알고리즘군을 별도의 클래스 집합으로 캡슐화,
2. 이 알고리즘군을 사용하는 객체에서 올바른 행동 인터페이스 구현하고, 이곳에 composition된 객체에 알고리즘군 인스턴스를 갈아끼우며 행동 실행을 delegation
=> Strategy Pattern은 알고리즘군을 정의, 캡슐화해서 각각의 알고리즘군을 관리, 수정, 사용할 수 있게 해준다.
전략패턴을 사용하면 Client로부터 알고리즘을 분리해서 독립적으로 변경할 수 있다.
디자인패턴03-Decorator 패턴 with Java (0) | 2022.10.07 |
---|---|
디자인패턴02 - Observer 패턴_ Java (0) | 2022.09.29 |