전략 패턴(Strategy Pattern)이란?
전략 패턴(Strategy Pattern)은 객체의 행위를 동적으로 변경할 수 있도록 설계된 디자인 패턴이다. 동일한 기능을 수행하는 여러 알고리즘(전략)을 클래스로 분리하고, 실행 중에 필요에 따라 적절한 전략을 선택할 수 있도록 한다. 이를 통해 유지보수성을 높이고, 코드 수정 없이 기능을 확장할 수 있는 장점이 있다.
예를 들어, 자동차, 기차, 버스 등의 이동 수단을 개발한다고 가정해 보자. 각 이동 수단은 도로 또는 철도를 따라 움직일 수 있는데, 이런 이동 방식이 정해진 것이 아니라 필요에 따라 변경될 수 있다. 전략 패턴을 적용하면 이동 방식을 인터페이스로 정의하고, 실행 중에 도로 또는 철도 이동 전략을 동적으로 선택할 수 있다.
1. 전략 패턴의 정의 및 구조
전략 패턴은 행위를 정의하는 인터페이스와 이를 구현하는 여러 개의 전략 클래스, 그리고 실행 시점에서 전략을 선택하는 컨텍스트(Context) 클래스로 구성된다.
구조
1. 전략 인터페이스(Strategy)
• 수행될 알고리즘(행위)을 정의하는 인터페이스
• 예: MovableStrategy 인터페이스를 만들어 이동 방식을 정의
2. 전략 구현 클래스(Concrete Strategies)
• 전략 인터페이스를 구현한 다양한 클래스
• 예: RailLoadStrategy(철도 이동), RoadStrategy(도로 이동)
3. 컨텍스트(Context)
• 실행할 전략을 동적으로 선택하는 클래스
• 예: Moving 클래스가 이동 전략을 결정
Java 코드 예제
// 1. 전략 인터페이스 정의
interface MovableStrategy {
void move();
}
// 2. 전략 클래스 구현 (철도 이동)
class RailLoadStrategy implements MovableStrategy {
public void move() {
System.out.println("이동: 철도를 따라 이동합니다.");
}
}
// 2. 전략 클래스 구현 (도로 이동)
class RoadStrategy implements MovableStrategy {
public void move() {
System.out.println("이동: 도로를 따라 이동합니다.");
}
}
// 3. 컨텍스트 클래스 (전략을 설정하고 실행)
class Moving {
private MovableStrategy strategy;
public void setMovableStrategy(MovableStrategy strategy) {
this.strategy = strategy;
}
public void move() {
strategy.move();
}
}
// 4. 실행 예제
public class StrategyPatternExample {
public static void main(String[] args) {
Moving bus = new Moving();
// 도로 이동 전략 설정
bus.setMovableStrategy(new RoadStrategy());
bus.move(); // 출력: 이동: 도로를 따라 이동합니다.
// 철도 이동 전략 설정
bus.setMovableStrategy(new RailLoadStrategy());
bus.move(); // 출력: 이동: 철도를 따라 이동합니다.
}
}
✔️ 실행 결과
이동: 도로를 따라 이동합니다.
이동: 철도를 따라 이동합니다.
위 코드에서 Moving 클래스는 MovableStrategy를 이용해 이동 전략을 설정할 수 있으며, 실행 중에 setMovableStrategy() 메서드를 사용해 전략을 변경할 수 있다.
2. 전략 패턴의 장점과 단점
장점
1. 유연성 증가
• 실행 중에 알고리즘을 동적으로 교체할 수 있어 유지보수성이 향상됨
2. OCP(Open-Closed Principle, 개방-폐쇄 원칙) 준수
• 기존 코드를 수정하지 않고 새로운 전략을 추가하여 기능을 확장할 수 있음
3. 캡슐화된 설계
• 알고리즘을 별도의 클래스로 분리하여 코드 가독성을 높이고 관리하기 쉬움
단점
1. 클래스 수 증가
• 전략 클래스가 많아지면 코드가 복잡해질 수 있음
2. 클라이언트 코드의 부담 증가
• 클라이언트가 실행 시점에 적절한 전략을 직접 설정해야 함
3. 유사한 디자인 패턴 소개
1) 상태 패턴(State Pattern)
• 전략 패턴과 유사하지만 객체의 상태(state)에 따라 동작이 달라진다는 점이 차이점
• 예를 들어, Player 객체가 “정상”, “피로”, “부상” 상태를 가질 수 있고, 상태에 따라 이동 속도가 다르면 상태 패턴을 적용하는 것이 적절함
• 차이점: 전략 패턴은 실행 중에 전략을 선택하지만, 상태 패턴은 상태 변경에 따라 자동으로 행동이 변경됨
2) 템플릿 메서드 패턴(Template Method Pattern)
• 공통된 알고리즘의 기본 틀을 유지하면서 일부 단계를 하위 클래스에서 구현하도록 하는 패턴
• 예를 들어, Animal 클래스에서 eat() 메서드는 공통 동작이지만, makeSound()는 각각 다르게 구현할 수 있음
• 차이점: 템플릿 메서드는 코드 재사용성이 높지만, 실행 중에 전략을 바꿀 수 없다는 한계가 있음
3) 데코레이터 패턴(Decorator Pattern)
• 객체에 동적으로 새로운 기능을 추가하는 패턴
• 예를 들어, 기본 Coffee 클래스가 있고 Milk, Sugar 데코레이터를 추가하면 다양한 커피를 조합할 수 있음
• 차이점: 전략 패턴은 객체의 행동을 바꾸는 데 초점이 있고, 데코레이터 패턴은 기능을 추가하는 데 집중됨
전략 패턴(Strategy Pattern)은 행위를 동적으로 변경하고 유지보수를 쉽게 하기 위한 디자인 패턴으로, 다양한 알고리즘을 독립적으로 정의하고 실행 중에 선택할 수 있도록 한다. 특히, OCP(개방-폐쇄 원칙)를 준수하여 코드 수정 없이 새로운 전략을 추가할 수 있는 것이 가장 큰 장점이다.
하지만 클래스 수 증가 및 클라이언트 코드의 부담 증가와 같은 단점도 있으므로, 필요할 때 적절히 활용해야 한다. 또한, 유사한 패턴인 상태 패턴, 템플릿 메서드 패턴, 데코레이터 패턴과 비교하여 적절한 패턴을 선택하는 것이 중요하다.
'JAVA-기초 > Design Pattern' 카테고리의 다른 글
[Design Pattern / Java] Template Method패턴 (1) | 2024.03.28 |
---|---|
[Design Pattern / Java] Factory Method(공장처럼 찍어내는 인터페이스) (0) | 2024.03.22 |
[Design Pattern] - Adapter 패턴 (92) | 2023.09.03 |
[Java] Design Pattern - Iterator ,For 반복문의 차이 (31) | 2023.08.20 |