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

Damsul·2023년 1월 12일
0

디자인패턴

목록 보기
11/15
post-thumbnail

행위를 클래스로 캡슐화하여 행위를 자유롭게 바꿀 수 있도록 하는 행위 패턴

  1. 클라이언트에 독립적으로 문제 해결 전략을 바꾸고 싶을때
  2. 다양한 문제해결 방법을 제공해야할때
    사용한다.

출처 : 위키디피아

  • Strategy : 알고리즘에 대한 공통 연산을 정의한 인터페이스
  • ConcreteStrategy : Strategy 인터페이스 구현체로, 실제 알고리즘 구현
  • Context : 실제 알고리즘을 사용하는 클래스

예제

게임 캐릭터의 직업 전사를 구현한다고 가정해보자. Strategy Pattern을 이용하면 대검, 도끼 등의 무기변경을 주입하여 유연하게 공격할 수 있다.

  • Strategy / ConcreteStrategy

[WeaponBehavior.java]

// Strategy
public interface WeaponBehavior { 
    void attack();
    String getWeaponType();
}

// ConcreteStrategy
class Sword implements WeaponBehavior {
    String type = "대검";

    @Override
    public void attack() {
        System.out.println("칼로 공격!");
    }

    @Override
    public String getWeaponType() {
        return type;
    }
}

class Axe implements WeaponBehavior {
    String type = "도끼";

    @Override
    public void attack() {
        System.out.println("도끼로 공격!");
    }

    @Override
    public String getWeaponType() {
        return type;
    }
}

[MoveBehavior.java]

// Strategy
public interface MoveBehavior {
    void move();
}

// ConcreteStrategy
class WalkBehavior implements MoveBehavior{
    @Override
    public void move() {
        System.out.println("걸어서 이동");
    }
}

class RunBehavior implements MoveBehavior {
    @Override
    public void move() {
        System.out.println("달려서 이동");
    }
}
  • Context

[Character.java] / Super Class

public abstract class Character {
	WeaponBehavior weaponBehavior;
    MoveBehavior moveBehavior;
    
    public void performAttack() { // 기본 공격 설정
        this.weaponBehavior.attack();
    }
    public void performMove() { // 기본 이동 방법 설정
        this.moveBehavior.move();
    }

    public void setWeapon(WeaponBehavior weapon) { // 무기 교체
        this.weaponBehavior = weapon;
    }

    public void setMoveBehavior(MoveBehavior moveBehavior) { // 이동 방법 변경
        this.moveBehavior = moveBehavior;
    }

    public String getWeaponType() {
        return this.weaponBehavior.getWeaponType();
    }

    public abstract String getJobClass();
}

[Warrior.java] / Sub Class

public class Warrior extends Character {
    String jobClass = "전사";
    public Warrior(WeaponBehavior weapon) {
        weaponBehavior = weapon;
        moveBehavior = new WalkBehavior();
    }

    @Override
    public String getJobClass() {
        return jobClass;
    }
}
  • Client

[Client.java]

public class Client {
    public static void main(String[] args) {
        Character warrior = new Warrior(new Sword());
        System.out.println("직업 : " +warrior.getJobClass());
        System.out.println("무기 : " + warrior.getWeaponType());
        warrior.performAttack();
        warrior.performMove();
        System.out.println();

        warrior.setWeapon(new Axe());
        warrior.setMoveBehavior(new RunBehavior());
        System.out.println("직업 : " +warrior.getJobClass());
        System.out.println("무기 : " + warrior.getWeaponType());
        warrior.performAttack();
        warrior.performMove();
    }
}
  • 실행 결과

장단점

  • 장점

    • 기존 컨텍스트의 변경없이 새 전략을 추가할 수 있다.
    • 런타임에 전략을 변경할 수 있다.
  • 단점

    • 전략이 추가되는 만큼 클래스가 많아진다.
      • 복잡도가 증가할 수 있다.
    • 클라이언트가 구체적인 전략을 알아야 한다.
profile
내 맘대로 작성하는 개발일지/ 작고 소중한 개발창고

0개의 댓글