
객체가 할 수 있는 유사한 행위들을 캡슐화하는 인터페이스를 정의하고, 각각의 행위에 대한 전략 클래스를 생성하여 객체의 행위를 동적으로 바꾸고 싶을 때 직접 행위를 수정하지 않고 전략을 바꿔주는 디자인 패턴.
전략을 사용하는 클라이언트와는 독립적으로 생성.
객체의 행위를 유연하게 확장하기 위한 디자인 패턴.
클라이언트는 시스템에 영향을 주지 않고 런타임에 사용되는 알고리즘을 변경 가능

move(), temperature() 라는 2개의 행위가 가능하고 각각의 행위는 2종류의 기능이 가능 public abstract class Robot {
public abstract void move();
public abstract void temperature();
}
public class HotAndWalkingRobot extends Robot {
@Override
public void move() {
System.out.println("I'm walking now.");
}
@Override
public void temperature() {
System.out.println("It's hot.");
}
}
public class ColdAndWalkingRobot extends Robot {
@Override
public void move() {
System.out.println("I'm walking now.");
}
@Override
public void temperature() {
System.out.println("It's cold.");
}
}
public class HotAndRunningRobot extends Robot {
@Override
public void move() {
System.out.println("I'm running now.");
}
@Override
public void temperature() {
System.out.println("It's hot.");
}
}
public class ColdAndRunningRobot extends Robot {
@Override
public void move() {
System.out.println("I'm running now.");
}
@Override
public void temperature() {
System.out.println("It's cold.");
}
}
public class Main {
public static void main(String[] args) {
Robot robot = new HotAndWalkingRobot();
robot.move();
robot.temperature();
}
}
// 전략을 사용하는 클라이언트
public class Robot {
private MoveStrategy moveStrategy;
private TemperatureStrategy temperatureStrategy;
public Robot(MoveStrategy moveStrategy, TemperatureStrategy temperatureStrategy) {
this.moveStrategy = moveStrategy;
this.temperatureStrategy = temperatureStrategy;
}
public void move() {
moveStrategy.move();
}
public void temperature() {
temperatureStrategy.temperature();
}
}
// 유사한 행위를 하나의 인터페이스로 정의하고 각 행위를 클래스로 구현
public interface MoveStrategy {
void move();
}
public class Walk implements MoveStrategy {
@Override
public move() {
System.out.println("I'm walking now.");
}
}
public class Run implements MoveStrategy {
@Override
public move() {
System.out.println("I'm running now.");
}
}
public interface TemperatureStrategy {
void temperature();
}
public class Hot implements TemperatureStrategy {
@Override
public temperature() {
System.out.println("It's hot.");
}
}
public class Cold implements TemperatureStrategy {
@Override
public temperature() {
System.out.println("It's cold.");
}
}
// 사용할 전략을 객체 생성 시 전달
public class Main {
public static void main(String[] args) {
Robot robot = new Robot(new Walk(), new Cold());
robot.move();
robot.temperature();
}
}
리팩토링, 유지보수를 할 때마다 객체 지향의 특성을 살려서 추상화를 잘하고 구조를 잘 잡는게 얼마나 중요한 일인지 매번 깨닫습니다. 그런 의미에서 디자인 패턴은 시간날 때 하나씩 공부하고 각 패턴을 비교하면 도움이 많이 될 것 같아서 시리즈로 정리하려고 합니다.
전략 패턴은 이전에 NestJs로 개발을 할때 Passport.js를 사용하면서 공부했던 기억이 납니다. 정리를 하자면, 알고리즘 집합을 캡슐화하여 클라이언트와 결합도를 낮추고 런타임에 동적으로 전략을 선택할 수 있게 해주는 패턴입니다.
서비스마다 다르겠지만 저의 경우 생각보다 기획의 변경으로 로직이 변경되는 상황이 빈번했습니다. 그래서인지 전략 패턴의 핵심인 전략의 동적 선택을 알아보기 위해서 공부했었는데, 각 알고리즘을 캡슐화하여 유지보수를 쉽게 만들어주는 점이 더 인상 깊었던 것 같습니다 😄