전략 패턴 (Strategy Pattern)

종명·2021년 4월 21일
1

헤드 퍼스트 디자인 패턴을 읽고 정리한 글입니다.

전략 패턴(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의 구현체를 생성하고 있다.

0개의 댓글