[Design Pattern] 스트래티지 패턴(Strategy Pattern)

시나브로·2021년 7월 10일
0

디자인 패턴

목록 보기
23/24
post-thumbnail

스트래티지 패턴(Strategy Pattern)


  • 행위(Behavioral) 패턴
  • 행위를 클래스로 캡슐화해 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
  • 같은 문제를 해결하는 여러 알고리즘이 클래스별로 캡슐화되어 있고 이들이 필요할 때 교체할 수 있도록 함으로써 동일한 문제를 다른 알고리즘으로 해결할 수 있게 하는 디자인 패턴



구조


  • Strategy
    • 인터페이스나 추상 클래스로 외부에서 동일한 방식으로 알고리즘을 호출하는 방법을 명시
  • ConcreteStrategy
    • 스트래티지 패턴에서 명시한 알고리즘을 실제로 구현한 클래스
  • Context
    • 스트래티지 패턴을 이용하는 역할을 수행한다.
      필요에 따라 동적으로 구체적인 전략을 바꿀 수 있도록 setter 메서드(‘집약 관계’)를 제공한다.



구현


로봇 만들기


AttackStrategy.class

public interface AttackStrategy { void attack(); }

MissileStrategy.class

public class MissileStrategy implements AttackStrategy {
    public void attack() { System.out.println("I have Missile."); }
}

PunchStrategy.class

public class PunchStrategy implements AttackStrategy {
    public void attack() { System.out.println("I have strong punch."); }
}

  • 공격 방법에 대한 전략을 구현한다.



MovingStrategy.class

public interface MovingStrategy { void move(); }

FlyingStrategy.class

public class FlyingStrategy implements MovingStrategy {
    public void move() { System.out.println("I can fly."); }
}

WalkingStrategy.class

public class WalkingStrategy implements MovingStrategy {
    public void move() { System.out.println("I can only walk."); }
}

  • 이동 방법에 대한 전략을 구현한다.
  • 각 전략들을 캡슐화하여 차후 추가 및 변경 시, Robot에 대한 변겅은 발생하지 않도록 한다



Robot.class

public abstract class Robot {
    private String name;
    private AttackStrategy attackStrategy;
    private MovingStrategy movingStrategy;

    public Robot(String name) { this.name = name; }
    public String getName() { return name; }
    public void attack() { attackStrategy.attack(); }
    public void move() { movingStrategy.move(); }

    // 집약 관계, 전체 객체가 메모리에서 사라진다 해도 부분 객체는 사라지지 않는다.
    // setter 메서드
    public void setAttackStrategy(AttackStrategy attackStrategy) {
        this.attackStrategy = attackStrategy; }
    public void setMovingStrategy(MovingStrategy movingStrategy) {
        this.movingStrategy = movingStrategy; }
}

TaekwonV.class

public class TaekwonV extends Robot {
    public TaekwonV(String name) { super(name); }
}

Atom.class

public class Atom extends Robot {
    public Atom(String name) { super(name); }
}

  • 각 상황에 맞는 Strategy를 받아 수행한다



Main.class

      public static void main(String[] args) {
        Robot taekwonV = new TaekwonV("TaekwonV");
        Robot atom = new Atom("Atom");

        /* 수정된 부분: 전략 변경 방법 */
        taekwonV.setMovingStrategy(new WalkingStrategy());
        taekwonV.setAttackStrategy(new MissileStrategy());
        atom.setMovingStrategy(new FlyingStrategy());
        atom.setAttackStrategy(new PunchStrategy());

        /* 아래부터는 동일 */
        System.out.println("My name is " + taekwonV.getName());
        taekwonV.move();
        taekwonV.attack();

        System.out.println();
        System.out.println("My name is " + atom.getName());
        atom.move();
        atom.attack();
    }

실행결과

>>>My name is TaekwonV
>>>I can only walk.
>>>I have Missile.

>>>My name is Atom
>>>I can fly.
>>>I have strong punch.



장단점


  • 장점
    • 컨텍스트 코드의 변경 없이 새로운 전략을 추가할 수 있다.
    • 즉, 컨텍스트에 대한 OCP 원칙을 만족하게 된다.
  • 단점
    • 사용되는 전략이 적다면, 복잡성만 늘어난다






참조:

profile
Be More!

0개의 댓글