suyeonme

[디자인 패턴] 전략 패턴(Strategy Pattern) 본문

프로그래밍👩🏻‍💻/디자인 패턴

[디자인 패턴] 전략 패턴(Strategy Pattern)

suyeonme 2022. 6. 18. 20:59
헤드 퍼스트 디자인 패턴을 읽고 정리한 내용입니다.

1. 문제 상황

1. Duck이라는 슈퍼 클래스가 있고 이 클래스를 확장하여 서로 다른 종류의 오리를 만들었다. 

2. 오리가 날 수 있는 기능을 추가해달라는 요건이 들어왔다.

3. Duck 슈퍼 클래스에 fly() 메소드를 추가했다. --> fly 기능을 가지면 안되는 서브 클래스들이 fly()를 상속받았다. 

4. fly 기능이 필요없는 서브 클래스에서는 fly()가 아무것도 하지 않도록 오버라이드한다.

5. 추가 요건이 계속 들어온다. (quack, eat, sleep등) --> 일일히 오버라이드할 수 없다.

 

2. 전략 패턴을 사용하여 해결

3.1 전략 패턴(Strategy Pattern)이란?

알고리즘군을 정의하고 캡슐화해서 각각의 알고리즘을 수정해서 쓸 수 있게 해준다. 전략 패턴을 사용하면 클라이언트로부터 알고리즘을 분리해서 독립적으로 변경할 수 있다.

 

즉 위에서 말한 알고리즘은 객체가 어떻게 행동(hebavior)할지에 대한 전략(strategy)이다. 따라서 아래와 같이 전략패턴을 사용할 수 있다.

 

  1. 행위(Behavior)에 맞는 전략을 위한 인터페이스를 만들어 추상화 한다.

  2. 해당 인터페이스를 구현한 전략 클래스는 각자 행위에 맞는 전략을 작성한다.

// Duck 슈퍼 클래스
public abstract class Duck {
  FlyBehavior flyBehavior;
  QuackBehavior quackBehavior;
  
  public Duck() {}
  
  public abstract void display();
  
  public void performFly() {
    flyBehavior.fly();
  }
  
    public void performQuack() {
    quackBehavior.quack();
  }
    
  public void setFlyBehavior(FlyBehavior fb) {
  	flyBehavior = fb;
  }
  
  public void setQuackBehavior(QuackBehavior qb) {
  	quackBehavior = qb;
  }
  
  public void swim() {
    System.out.println('오리가 물에 뜨다.');
  }
}

// FlyBehavior 인터페이스와 행동 구현 클래스
public interface FlyBehavior {
  public void fly();
}

public class FlyWithWings implements FlyBehavior {
  public void fly() {
    System.out.println('오리가 날다.');
  }
}

public class FlyNoWay implements FlyBehavior {
  public void fly() {
    System.out.println('오리가 날지 못하다.');
  }
}

// QuackBehavior 인터페이스와 행동 구현 클래스
public interface QuackBehavior {
  public void quack();
}

public class Quack implements QuackBehavior {
  public void quack() {
    System.out.println('꽥');
  }
}

public class MuteQuack implements QuackBehavior {
  public void quack() {
    System.out.println('쉿');
  }
}

 

3. 상황에 따라 자신에게 맞는 전략을 자유롭게 사용한다.

public class MallardDuck extends Duck {
  public MallardDuck() {
    quackBehavior = new Quack();
    flyBehavior = new FlyWithWings();
  }
  public void display() {
    System.out.println('나는야 물오리');
  }
}

// 사용 
Duck mallard = new MallardDuck();
mallard.performQuack();
mallard.performFly();
mallard.setFlyBebavior(new FlyRocketPowered()); // 동적으로 행동 변경
Comments