행동 (1) - 전략(Strategy) 패턴
- 기능을 인터페이스로 추상화하고 여러 알고리즘으로 상호 교환 가능하게 하는 패턴
- Strategy : 기능을 추상화 하는 인터페이스
- Concrete Strategy : 알고리즘을 실제로 구현하는 클래스
- Context : 전략을 호출하는 역할, 변하지 않는 템플릿 역할을 함
구현
- Strategy
public interface Movable {
public void move();
}
- Concrete Strategy
public class Train implements Movable {
@Override
public void move(){
System.out.println("Rail");
}
}
public class Bus implements Movable {
@Override
public void move(){
System.out.println("Road");
}
}
- Context : 변하지 않는 템플릿 역할을 함
- 생성자나 setter로 Concrete 전략을 선택한다
public class Context {
private Movable strategy;
public Context(Movable strategy) {
this.strategy = strategy;
}
public void move() {
strategy.move(); // 위임
}
}
- Client(Main 메서드)
public class Main {
public static void main(String args[]){
Train train = new Train();
Context context1 = new Context(train);
context1.move(); // Rail
Bus bus = new Bus();
Context context2 = new Context(bus);
context2.move(); // Road
}
}
익명 내부클래스 사용
- 클래스가 계속 늘어나는 것을 막기 위해 익명 내부클래스를 사용할 수도 있다
public class Main {
public static void main(String args[]){
// 익명 내부클래스 사용
Movable vehicle = new Movable() {
@Override
public void move() {
System.out.println("탈것이 움직입니다.");
}
};
Context context1 = new Context(vehicle);
context1.move();
// 람다 사용
Context context2 = new Context(() -> System.out.println("탈것이 움직입니다."));
context2.move();
}
}
파라미터 방식 (템플릿 콜백 패턴)
- 기본에는 필드에 Strategy를 저장하는 방식이였다 (선조립 후실행)
- 파라미터를 사용해서 실행시점에 전략을 유연하게 선택할 수도 있다
- 단점 : 실행할 때 마다 전략을 계속 만들어야 한다
public class Context {
public void move(Movable strategy) { // 파라미터로 전략을 받음
strategy.move();
}
}
public class Main {
public static void main(String args[]){
// 람다 사용
Context context = new Context();
context.move(() -> System.out.println("탈것이 움직입니다."));
}
}
- 템플릿 콜백 패턴 (명칭변경)
-
Context
->Template
-
Strategy
->Callback
-
public interface Callback {
public void move();
}
public class VehicleTemplate {
public void move(Callback callback) {
callback.move();
}
}
public class Main {
public static void main(String args[]){
// 람다 사용
VehicleTemplate template = new VehicleTemplate();
template.move(() -> System.out.println("탈것이 움직입니다."));
}
}
장점
- 새로운 전략이 추가되어도 기존 코드를 수정할 필요가 업다
- 런타임에서도 전략을 변경할 수 있다
단점
- 복잡도가 증가한다
- 클라이언트가 구체적인 전략을 알아야 한다