전략 바꾸기
Motivation
여러 클래스가 특정 역할에 대해 behavior 만 다르게구현 되는 경우가 많다.
이때 behavior logic (strategy)만 문리하여 그 알고리즘을 런타임에 선택할 수 있도록 하는것은 좋은 아이디어 이다.
Intent
- Algorithms 들만 모아서 그룹을 만들어 상호 변경 가능하도록 구현하자
Implementation

- Strategy - 모든 구체전략에 대한 인터페이스를 제공한다.
- ConcreteStrategy - 구체 전략
- Context
- 구체 전략에대한 참조를 전략 인터페이스에 담아 보관하고 있음
- 클라이언트의 요청이 들어올 시 실질적인 알고리즘의 실행은 구체 전략에 위임
Applicablity & Examples

public interface IBehaviour { public int moveCommand(); } public class AgressiveBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tAgressive Behaviour: if find another robot attack it"); return 1; } } public class DefensiveBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tDefensive Behaviour: if find another robot run from it"); return -1; } } public class NormalBehaviour implements IBehaviour{ public int moveCommand() { System.out.println("\tNormal Behaviour: if find another robot ignore it"); return 0; } } public class Robot { IBehaviour behaviour; String name; public Robot(String name) { this.name = name; } public void setBehaviour(IBehaviour behaviour) { this.behaviour = behaviour; } public IBehaviour getBehaviour() { return behaviour; } public void move() { System.out.println(this.name + ": Based on current position" + "the behaviour object decide the next move:"); int command = behaviour.moveCommand(); // ... send the command to mechanisms System.out.println("\tThe result returned by behaviour object " + "is sent to the movement mechanisms " + " for the robot '" + this.name + "'"); } public String getName() { return name; } public void setName(String name) { this.name = name; } } public class Main { public static void main(String[] args) { Robot r1 = new Robot("Big Robot"); Robot r2 = new Robot("George v.2.1"); Robot r3 = new Robot("R2"); r1.setBehaviour(new AgressiveBehaviour()); r2.setBehaviour(new DefensiveBehaviour()); r3.setBehaviour(new NormalBehaviour()); r1.move(); r2.move(); r3.move(); System.out.println("\r\nNew behaviours: " + "\r\n\t'Big Robot' gets really scared" + "\r\n\t, 'George v.2.1' becomes really mad because" + "it's always attacked by other robots" + "\r\n\t and R2 keeps its calm\r\n"); r1.setBehaviour(new DefensiveBehaviour()); r2.setBehaviour(new AgressiveBehaviour()); r1.move(); r2.move(); r3.move(); } }
Specific problems & Implementation
전략에 데이터 (Parameter/return) 주고 받기
보통 Strategy에는 데이터를 넘기고 받아야됨 두가지 방법이 있음
- 주고 받기 위한 클래스를 따로 만듬
- 단점 - 어떤 전략은 필드를 모두 필요 없음, 복잡함
- 전략 객체 자체에 주고 받을 데이터를 위한 필드를 만듬
- 단점 - 전략을 사용하는 문맥(Context)와 전략이 강하게 결함함
연관된 알고리즘의 그룹
- 그루핑을 할 수도 있고 계층을 나눌 수 도 있음.
- 이경우 Composite 디자인 패턴을 신중하게 사용해야함
Optionally Concrete Strategy Objects
Default 전략을 제공하여 전달받은 전략이 null인 경우 default 전략을 적용할 수 있음
전략패턴 + 생성패턴
클라이언트는 String과 같은 간단한 식별자만 전달 하여 여러 방식으로 생성된 객체를 사용할 수 있음
전략패턴과 브릿지패턴
- 둘은 같은 UML 구조를 가지지만 Intent가 다름
- 전략패턴은 행위와 관련이 있고 브릿지패턴은 구조와 관련이 있음
- 추가로 전략패턴의 context - strategies 가 브릿지패턴의 abstraction-implementation 보다 강하게 결합함