스트래티지 패턴 (Strategy Pattern)

  • 변하지 않는 부분을 제외한 변하는 부분에 대해서 캡슐화를 수행
  • 변하는 부분을 인터페이스로 선언하고 하위 클래스에서 변하는 부분들에 대한 상세 내용을 구현
  • IS A 관계보다는 HAS A 관계를 지향

 

상황

  • 게임에서 여러 캐릭터가 존재한다.
  • 캐릭터의 직업군은 다양한다. 검사/ 궁수/ 마법사/ 도적 등등
  • 각각의 직업군에서 사용하는 무기는 다르다. (사용하는 무기는 변한다.)
  • 각각의 직업군에서 사용하는 무기가 언제든 교체될 수 있다. (검사가 급하면 활을 사용할 수 있다는 의미)

우선 위의 상황에 대한 다이어그램은 아래와 같이 표현할 수 있다.

 

게임에 존재하는 캐릭터 (king/ Queen/ Troll/ Knight) 에 대한 무기 사용 다이어그램

  • Character 라는 추상클래스를 만들고 HAS A 관계로 weaponBehavior 라는 인터페이스를 필드로 가지고 있다.
  • weaponBehavior 인터페이스는 여러 행동들 (도끼/ 검/ 칼/ 활과 화살) 에 대한 행동들에 대해 구체화 시키기 위해 존재한다.
  • Character 추상클래스 하위에 King/ Queen/ Troll/ Knight 가 상속받고, 해당 추상클래스의 메소드인 fight() 를 오버라이딩 한다.
  • 실행 중에도 언제든지 자신의 직업군에 대한 무기 사용 행동을 변경할 수 있다.

 

Code

Character class

public abstract class Character {

    WeaponBehavior weaponBehavior = null;

    public abstract void fight();

    public void setWeapon(WeaponBehavior weaponBehavior){
        this.weaponBehavior = weaponBehavior;
    }

}

King class

public class King extends Character{

    public King(){
    	// 기본 생성자에서 King 은 검을 사용한다.
        weaponBehavior = new SwordBehavior();
    }

    @Override
    public void fight() {
        weaponBehavior.useWeapon();
    }
}

WeaponBehavior interface

public interface WeaponBehavior {

    void useWeapon();

}

SwordBehavior class

public class SwordBehavior implements WeaponBehavior {

    @Override
    public void useWeapon() {
        System.out.println("검을 사용한다.");
    }
}

Runner class 및 결과 내용

public class Runner {

    public static void main(String[]args){

        System.out.println("=====> King 의 무기 사용");

        King king = new King();
        king.fight();
        king.setWeapon(new AxeBehavior());          // 무기 변경
        king.fight();
        king.setWeapon(new BowAndArrowBehavior());  // 무기 변경
        king.fight();
        king.setWeapon(new SwordBehavior());        // 무기 변경
        king.fight();

        System.out.println("======================>");
    }
}
=====> King 의 무기 사용 
검을 사용한다. 
도끼를 사용한다. 
활과 화살을 사용한다. 
검을 사용한다. 
======================>

 

전체 소스코드는 GitHub 에 있다.

 

reference

Head First - Design Patterns

구루비 Dev Study - 스트래티지 패턴

Posted by doubler
,