01. Strategy Pattern

같은 종류의 작업을 하는 알고리즘을 정의
각 알고리즘을 캡슐화, 그리고 알고리즘들을 서로 바꿔 사용할 수 있도록 함

→ 모든 알고리즘이 동시에 사용되는 것이 아니면 굳이 함께 넣어야 할 필요 없음
알고리즘을 런타임때 선택할 때 필요한 패턴

ex) 카메라 앱 필터: 카메라 앱에 모두 내장시킬 필요는 없음
→ 필터 추가할 때 전체를 업데이트 vs 필터만 추가

  1. Context
    strategy, executeStrategy(), setStrategy()를 포함함
    캡슐화된 알고리즘을 멤버 변수로 포함
    캡슐화된 알고리즘을 교환해서 적용시킬 수 있음
  2. Strategy 인터페이스
    컴파일 시점에 사용하는 캡슐화된 알고리즘 나타냄
    실제 구현은 하위 Strategy n 클래스에 위임
    인터페이스 or 추상 클래스로 구현
  3. Strategy n
    실행 시점에 적용될 알고리즘 캡슐화
    Context에서 실행될 알고리즘 구현

사례1 - Duck(HFDP Ch.1)

Problem

  • Duck에 fly()를 추가하면, 필요없는 부분에도 fly()가 적용이 됨
  • 상황에 따라 바뀌는 부분을 분리하자
    - ex1) duck: fly(), quack()
    - ex2) ramen: recipy()

Strategy Pattern 적용


Duck

public 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 void display(){
        System.out.println("display");
    }
}
public class MallardDuck extends Duck {

    public MallardDuck(){
        setQuackBehavior(new Quack()); //상황에 맞는 객체 생성해서 넣음
        setFlyBehavior(new FlyWithWings());
    }

    @Override
    public void display() {
        System.out.println("mallard Duck");
    }
}

사례2 - 라면 조리

1. 바뀌는 부분: recipe 분리 -> interface
2. interface 구현

public interface CookRecipe {
    public void cook();
}
public class CheeseRecipe implements CookRecipe{
    @Override
    public void cook() {
        System.out.println("CheeseRecipe");
    }
}

3. Context 구현 = interface를 멤버 필드로 가지는 객체 생성
: interface 구현체의 함수 호출하는 메소드 추가, interface는 setter로 변경 가능

public class Ramen {
    private CookRecipe cookRecipe;

    //변경이 가능하도록 함
    public void setCookRecipe(CookRecipe cookRecipe) {
        this.cookRecipe = cookRecipe;
    }

    public void performCook(){
        cookRecipe.cook();
    }
}

4. main

public class main {
    public static void main(String[] args) {
        Ramen r = new Ramen();
        r.setCookRecipe(new CheeseRecipe());

        r.performCook();
    }
}

좋은 웹페이지 즐겨찾기