📕 목차
1. Strategy Pattern
2. 예시 코드
1. Strategy Pattern
📌 전략 패턴
- 정책 패턴(policy pattern)이라고도 한다.
- 실행(런타임) 중에 객체의 행위를 바꾸는 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체하는 패턴
- 전략이란 일종의 알고리즘이며, 특정 목표를 수행하기 위한 기능이나 동작 계획을 말한다.
- 어떤 일을 수행하는 알고리즘이 여러가지 일 때, 변형이 빈번하게 필요한 경우 적합하다.
- 결제 방법은 네이버 페이, 카카오 페이 등 다양한 방법이 존재한다.
- OAuth 인증 방법은 네이버, 카카오, 구글, 애플 등 다양한 방법이 존재한다.
- 구조
- 클라이언트: 특정 전략 객체를 Context에 전달하여, 전략을 등록하거나 전략 알고리즘 실행 결과를 받는다.
- Context: 알고리즘을 실행해야 할 때마다, 해당 알고리즘과 연결된 전략 객체 메서드 호출
- 전략 인터페이스: 모든 전략 구현체에 대한 공용 인터페이스
- 전략 알고리즘 객체: 알고리즘, 행위, 동작을 객체로 정의한 구현체
📌 OOP의 집합체
- 동일 계열의 알고리즘군을 정의하고 → 전략 구현체 정의
- 각각의 알고리즘을 캡슐화하여 → 전략 인터페이스로 추상화
- 이들을 상호교환이 가능하도록 만든다 → 컴포지션으로 구성
- 알고리즘을 사용하는 클라이언트와 상관없이 독집적으로 → 컨텍스트 수정 없이
- 알고리즘을 다양하게 변경할 수 있다 → 메서드를 통해 전략 객체를 실시간으로 변경
📌 코드 패턴
🟡 전략 인터페이스와 구현체
// 전략(추상화된 알고리즘)
interface Strategy {
void doSomething();
}
// 전략 알고리즘 A
class ConcreteStrategyA implements Strategy {
public void doSomething() {}
}
// 전략 알고리즘 B
class ConcreteStrategyB implements Strategy {
public void doSomething() {}
}
🟡 컨텍스트
class Context {
Strategy strategy;
public Context(IStrategy strategy) {
this.strategy = strategy;
}
// 전략 실행 메소드
void doSomething() {
strategy.doSomething();
}
}
🟡 클라이언트
class Client {
public static void main(String[] args) {
Context context = new Context(new ConcreteStrategyA);
context.doSomthing();
}
}
📌 사용 시기
- 전략 알고리즘이 여러 버전 또는 변형이 필요할 때 클래스화하여사용
- 알고리즘 코드가 노출되어서는 안 되는 데이터에 접근하는 경우 (캡슐화)
- 알고리즘 동작이 런타임에 실시간으로 교체되어야 할 때
📌 주의점
- 알고리즘이 많아질 수록 관리해야 할 객체 수가 늘어난다.
- 애플리케이션 특성 상 알고리즘이 많지 않고, 자주 변경되지 않는다면 굳이 분리해서 복잡도를 올릴 필요가 없다.
- 개발자는 적절한 전략을 선택하기 위해 전략 간 차이점을 파악하고 있어야 한다.
2. 예시 코드
📌 결제 전략 인터페이스
public interface PaymentStrategy {
void pay(int amount);
}
📌 전략 구현체
1️⃣ 카카오 카드 결제 전략
public class KAKAOCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvc;
private String dateOfExpiry;
public KAKAOCardStrategy(String name, String cardNumber, String cvc, String dateOfExpiry) {
this.name = name;
this.cardNumber = cardNumber;
this.cvc = cvc;
this.dateOfExpiry = dateOfExpiry;
}
@Override
public void pay(int amount) {
System.out.println(amount + "원을 카카오 카드로 결제합니다.");
}
}
2️⃣ 네이버 카드 결제 전략
public class NAVERCardStrategy implements PaymentStrategy {
private String email;
private String password;
public NAVERCardStrategy(String email, String password) {
this.email = email;
this.password = password;
}
@Override
public void pay(int amount) {
System.out.println(amount + "원을 네이버 카드로 결제합니다.");
}
}
📌 Context
public class ShoppingCart {
private List<Item> items = new ArrayList<>();
public void addItem(Item item) {
items.add(item);
}
public void removeItem(Item item) {
items.remove(item);
}
public int calculateTotal() {
int sum = 0;
for (Item item : items) {
sum += item.getPrice();
}
return sum;
}
public void pay(PaymentStrategy paymentMethod) {
int amount = calculateTotal();
paymentMethod.pay(amount);
}
}
📌 Client
public class Client {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("컴퓨터", 1000000);
Item item2 = new Item("키보드", 50000);
cart.addItem(item1);
cart.addItem(item2);
// 카카오 카드로 결제
cart.pay(new KAKAOCardStrategy("홍길동", "1234-1234-1234-1234", "123", "12/24"));
// 네이버 카드로 결제
cart.pay(new NAVERCardStrategy("a@a.com", "1234"));
}
}