전략 패턴 (Strategy Pattern)

신민철·2023년 6월 4일
0

전략 패턴 (Strategy Pattern)

전략 패턴은 객체들이 할 수 있는 행위 각각에 대해 전략 클래스를 생성하고, 유사한 행위들을 캡슐화하는 인터페이스를 정의하여, 객체의 행위를 동적으로 바꾸고 싶은 경우 행위를 직접 수정하지 않고 전략을 바꿔주는 유연한 확장 방법을 말합니다.

사용 이유

전략 패턴은 알고리즘의 변경이나 추가가 필요할 때, 기존 코드를 수정하지 않고도 새로운 알고리즘을 추가하거나 변경할 수 있습니다. 또한, 알고리즘을 사용하는 클라이언트와 분리하여 유지보수성과 확장성을 높일 수 있습니다.

public interface Material {
	public void made();
}
public class Sword implements Material {
	public void made() {
		System.out.println("이 검은 철로 만들어져 있습니다.");
	}
}
public class Bow implements Material {
	public void made() {
		System.out.println("이 활은 나무로 만들어져 있습니다.");
	}
}
public class Client {
	public static void main(String args[]) {
		Material sword = new Sword();
		Material bow = new Bow();

		sword.made();
		bow.made();
	}
}

기존의 검은 철로 만든 검밖에 없고, 활은 나무로 만든 활밖에 없다고 생각해봅시다. 하지만 시간이 지나, 철로 활을 만들었습니다.

그러면 메소드의 내용을 바꿔주면 됩니다.

public void made() {
		System.out.println("이 활은 철로 만들어져 있습니다.");
}

하지만 이렇게 변경하는 순간, SOLID의 OCP(Open-Closed Principle)에 위배됩니다.

OCP에 의하면 기존의 made()를 수정하지 않고 행위가 수정되어야 하지만, 지금은 made() 메소드를 직접 수정했기 때문입니다.

그럼 전략 패턴을 사용하는 구조로 개선해보겠습니다.

public interface MaterialStrategy {
	public void made();
}
public class SteelStrategy implements MaterialStrategy {
	public void made() {
		System.out.println("이 것은 철로 만들어져 있습니다.");
	}
}

public class WoodStrategy implements MaterialStrategy {
	public void made() {
		System.out.println("이 것은 나무로 만들어져 있습니다.");
	}
}

이제 각자 어떤 Strategy를 설정하기 위해 setMaterialStrategy() 메소드를 만들어야 합니다.

public class Making {
	private MaterialStrategy materialStrategy;

	public void made() {
		materialStrategy.made();
	}

	public void setMaterialStrategy(MaterialStrategy materialStrategy) {
		this.materialStrategy = materialStrategy;
	}
}
public class Sword extends Making {}
public class Bow extends Making {}

전략 패턴을 사용하여 각 도구의 재료를 바꿀 수 있게 다음과 같이 Client 코드를 작성할 수 있습니다.

public class Client {
	public static void main(String args[]) {
		Making sword = new Sword();
		Making bow = new Bow();

		/* 기존의 방식 */
		sword.setMaterialStrategy(new SteelStrategy());
		bow.setMaterialStrategy(new WoodStrategy());

		sword.made();
		bow.made();

		/* 철로 만들어진 활이 개발되었을 때 전략 교체 */
		bow.setMaterialStrategy(new SteelStrategy());

		bow.made();
	}
}

위와 같은 방식으로 도구의 재료가 바뀌었다고 해서 내부 코드를 변경하여 OCP 원칙을 위배하는 일이 없게 됩니다.

0개의 댓글