알고리즘의 패밀리를 정의하며 알고리즘을 객체로 만들어 갭슐화하고 별도의 클래스에 넣은 후 패밀리에 해당하는 전략객체들을 상호교환 할 수 있도록 하는 패턴이다.
게임에서 캐릭터가 공격(attack)하는 방법에 검
, 활
, 도끼
가 있다 하자.
1. 캐릭터에 해당하는 Character 클래스는 다음과 같다.
public class Character {
public void attack(String type) {
if (type.equals("Sword")) {
System.out.println("Sword attack.");
} else if (type.equals("Bow")) {
System.out.println("Bow attack.");
} else if (type.equals("Ax")) {
System.out.println("Ax attack.");
}
}
}
위의 구조는 새로운 공격 방식이 추가될 때 Character의 attck을 변경해야한다. 그리고 attack외에 다른 방어(defense)메소드가 추가된다면? 각 메소드에 if-else문이 반복되고 코드의 가독성이 크게 떨어질 것이다.
전략(Strategy)객체를 만들어 전략에 해당하는 행동을 '전략객체'에 위임하자
1. AttackStrategy
public interface AttackStrategy {
void attack();
}
구조에서 Strategy에 해당하는 인터페이스로 Context에서 사용할 attack 메소드를 정의한다.
2. Sword, Bow, Ax AttackStrategy
public class SwordAttackStrategy implements AttackStrategy {
@Override
public void attack() {
System.out.println("Sword attack.");
}
}
public class BowAttackStrategy implements AttackStrategy {
@Override
public void attack() {
System.out.println("Bow attack.");
}
}
public class AxAttackStrategy implements AttackStrategy {
@Override
public void attack() {
System.out.println("Ax attack.");
}
}
ConcreteStrategy에 해당하는 AttackStrategy이며 attack을 오버라이딩한다.
3. Character
public class Character {
private AttackStrategy strategy;
public Character(AttackStrategy strategy) {
this.strategy = strategy;
}
public void setStrategy(AttackStrategy strategy) {
this.strategy = strategy;
}
public void attack() {
strategy.attack();
}
}
Context(Character)를 사용하는 Client는 Character의 전략을 setStrategy를 통해 전략을 교체할 수 있다.
두 패턴은 행위 자체를 별도의 클래스(State, Strategy)로 캡슐화 하고, 연관 관계를 이용해 행위를 캡슐화한 클래스(Concrete Class)에 실제 작업 수행을 위임하는 측면에서 동일하다. 또한 두 패턴은 실행 중에 행위를 변경할 수 있다.
JAVA 객체지향 디자인패턴 - CHAPTER 07 연습문제 1번