헤드 퍼스트 디자인 패턴을 읽고 정리한 글입니다.
전략 패턴(strategy pattern)은 알고리즘군을 정의하고 각각을 캡슐화하여 교환해서 사용할 수 있도록 만듭니다. 알고리즘을 사용하는 클라이언트와는 독립적으로 알고리즘을 변경할 수 있다.
오리는 '소리 내는 행동'과 '나는 행동'을 가지고 있고 수정자를 통해 바꿀 수 있다.
abstract class Duck {
FlyBehavior flyBehavior;
QuackBehavior quackBehavior;
public void setFlyBehavior(FlyBehavior flyBehavior) {
this.flyBehavior = flyBehavior;
}
public void setQuackBehavior(QuackBehavior quackBehavior) {
this.quackBehavior = quackBehavior;
}
public void performFly() {
flyBehavior.fly();
}
public void performQuack() {
quackBehavior.quack();
}
public abstract void display();
}
먼저 FlyBehavior를 살펴보자. FlyBehavior라는 인터페이스와 3가지의 구현체가 있다.
public interface FlyBehavior {
void fly();
}
public class FlyNoWay implements FlyBehavior{
@Override
public void fly() {
System.out.println("저는 못 날아요");
}
}
public class FlyWithWings implements FlyBehavior{
@Override
public void fly() {
System.out.println("날고 있어요!!!");
}
}
public class FlyRocketPowered implements FlyBehavior{
@Override
public void fly() {
System.out.println("로켓 추진으로 날아갑니다~~");
}
}
다음으로 QuackBehavior를 살펴보자. QuackBehavior라는 인터페이스와 2가지의 구현체를 만들었다.
public interface QuackBehavior {
void quack();
}
public class Quack implements QuackBehavior{
@Override
public void quack() {
System.out.println("꽥");
}
}
public class MuteQuack implements QuackBehavior{
@Override
public void quack() {
System.out.println("조용...");
}
}
다음을 활용해 오리를 만들어보자. 두가지 오리를 만들어보자.
public class MallardDuck extends Duck{
public MallardDuck() {
quackBehavior = new Quack();
flyBehavior = new FlyWithWings();
}
@Override
public void display() {
System.out.println("물 오리 입니다!");
}
}
public class ModelDuck extends Duck{
public ModelDuck() {
flyBehavior = new FlyNoWay();
quackBehavior = new Quack();
}
@Override
public void display() {
System.out.println("모형 오리 입니다!");
}
}
main 메소드에서 실행해보면 다음과 같은 결과를 볼 수 있다.
Duck mallardDuck = new MallardDuck();
mallardDuck.display(); // 물 오리 입니다!
mallardDuck.performFly(); // 날고 있어요!!!
mallardDuck.performQuack(); // 꽥
Duck modelDuck = new ModelDuck();
modelDuck.display(); // 모형 오리 입니다!
modelDuck.performFly(); // 저는 못 날아요
modelDuck.performQuack(); // 꽥
// 만약 모형 오리의 나는 행동을 변경한다면 다음과 같이 변경할 수 있다.
modelDuck.setFlyBehavior(new FlyRocketPowered());
modelDuck.performFly(); // 로켓 추진으로 날아갑니다~~
위의 예제처럼 새로운 오리를 만들거나 이미 있던 오리의 행동을 바꾼다면 그 행동만 바꿔주면 된다.
마지막으로 아래는 위 예제의 클래스 다이어그램이다. Duck 클래스는 QuakBehavior, FlyBehavior 인터페이스를 포함하고 있고 각각의 Duck 구현체들은 QuackBehavior, FlyBehavior의 구현체를 생성하고 있다.