전략 패턴이란, 런타임 시점에 알고리즘을 선택하여 행동을 바꿀 수 있는 행위 디자인 패턴이다.
알고리즘 변경이 빈번하게 이뤄질 때 사용하기 적합한 패턴이다.
개인적으로 실무에서 가장 유용하게 사용하고 있는 디자인 패턴 중 하나로 서비스 특성 상 변경이 빈번하게 이뤄지고 있는 상황에서 적용하기 가장 적합한 패턴이라고 생각한다.
전략 패턴을 통해 코드의 복잡성을 줄인 경험이 있고, OOP에서 강조하는 내용들을 준수하며 유지보수가 용이한 코드를 작성할 수 있다.
Context는 알고리즘을 선택할 책임이 존재하지 않는다. 다만, 클라이언트가 원하는 전략을 Context에서 등록 실행을 하며 Context는 Strategy Interface와 조합(composition)
을 통해 동작을 한다.
여러 알고리즘들은 Strategy를 구현하고 있으며 캡슐화되어 인터페이스로 추상화
되어 있다. 그래서 Context는 개별 알고리즘에 대해 자세히 알지 못한다.
새로운 알고리즘이 필요하게 된다면 Context 또는 기존 알고리즘을 수정하지 않고 새로운 알고리즘을 추가 및 수정을 할 수 있게 됩니다. 즉, OCP 원칙을 준수
하게 된다.
이렇듯 전략 패턴을 사용하게 된다면 OOP에서 강조하는 내용인 OCP, DIP, 상속보다는 조합, 다형성, 캡슐화
등을 준수할 수 있게 된다.
public class StrategyPatternMain {
public static void main(String[] args) throws IOException {
InputStream in = System.in;
InputStreamReader reader = new InputStreamReader(in);
BufferedReader br = new BufferedReader(reader);
String input = br.readLine();
Context context = new Context();
if ("add".equals(input)) {
context.setStrategy(new ConcreteStrategyAdd());
} else if ("sub".equals(input)) {
context.setStrategy(new ConcreteStrategySubtract());
} else if ("mul".equals(input)) {
context.setStrategy(new ConcreteStrategyMultiply());
}
context.executeStrategy(10, 5);
}
}
public class Context {
private Strategy strategy;
public void setStrategy(Strategy strategy) {
this.strategy = strategy;
}
public int executeStrategy(int a, int b) {
return strategy.execute(a, b);
}
}
public interface Strategy {
int execute(int a, int b);
}
public class ConcreteStrategyAdd implements Strategy {
@Override
public int execute(int a, int b) {
return a + b;
}
}
public class ConcreteStrategySubtract implements Strategy {
@Override
public int execute(int a, int b) {
return a - b;
}
}
public class ConcreteStrategyMultiply implements Strategy {
@Override
public int execute(int a, int b) {
return a * b;
}
}
만약 spring을 사용하고 있다면 예제코드에서 보이는 setStrategy
코드를 사용하지 않고 추상화된 interface를 Collection으로 주입받아 client가 원하는 알고리즘을 Context에서 찾고 실행하게 된다면 이후 알고리즘을 추가할 때 Context 코드와 기존 알고리즘 코드는 전혀 수정할 필요가 없게된다.
앞서 말했듯이 전략 패턴을 잘 활용하게 된다면 더욱 가독성 높은 코드, 유지보수가 용이한 코드를 작성할 수 있게 된다. 현재 재직중인 회사에서도 800 라인에 가까운 코드를 단 2~3줄의 코드로 개선한 경험이 있는데 이에 대한 내용도 나중에 포스팅 할 예정이다.
참고
https://refactoring.guru/ko/design-patterns/strategy
헤드 퍼스트 디자인 패턴
https://inpa.tistory.com/entry/GOF-%F0%9F%92%A0-%EC%A0%84%EB%9E%B5Strategy-%ED%8C%A8%ED%84%B4-%EC%A0%9C%EB%8C%80%EB%A1%9C-%EB%B0%B0%EC%9B%8C%EB%B3%B4%EC%9E%90