Strategy Parttern이란?
객체의 행위를 캡슐화하여 동적으로 행위를 변경할 수 있도록 하는 디자인 패턴이다.
디자인 패턴 중 행위 패턴에 속한다.
Strategy Pattern을 쓰는 이유(==기존 개발 형태에 대한 문제점)?
예를 들어 "결제"라는 행위에 대해 기존 개발 방식처럼 구현해보자.
public class ShoppingCart {
private List<Item> items;
private String paymentMethod; // "CREDIT_CARD" or "CASH"
public ShoppingCart(String paymentMethod) {
this.items = new ArrayList<>();
this.paymentMethod = paymentMethod;
}
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 checkout() {
int amount = calculateTotal();
if (paymentMethod.equals("CREDIT_CARD")) {
// 신용카드 결제 로직
System.out.println(amount + " paid with credit card");
} else if (paymentMethod.equals("CASH")) {
// 현금 결제 로직
System.out.println(amount + " paid using cash");
}
}
}
OOP 설계 5대 원칙과 지금까지의 디자인 패턴을 학습했기 때문에 이 코드를 보면 거슬리는 부분이 있다.
어떤게? 또다른 결제 방식이 추가될때 변경에 닫혀있어야하는데 계속 checkout 메서드를 변경해야하는 것이 거슬린다.
아니면 현금 결제 로직에 현금영수증을 관리하는 것도 추가하고 싶은데 이럴 때 또 checkout 메서드를 변경해야한다.
다음과 같은 문제점과 불편함이 있다.
1. 유연성 부족
2. 유지보수가 어려움
Strategy Pattern(전략 패턴) 구현 방법
1. 전략 인터페이스: 공통된 메서드를 정의하는 인터페이스
2. 구체적인 전략 클래스: 전략 인터페이스를 구현한 구체적인 클래스들.
3. 컨텍스트 클래스: 클라이언트가 사용하는 인터페이스를 제공하고 전략 객체를 포함. 구체적인 전략 객체를 설정함.
1. 전략 인터페이스: 공통된 메서드를 정의하는 인터페이스
public interface PaymentStrategy {
void pay(int amount);
}
2. 구체적인 전략 클래스: 전략 인터페이스를 구현한 구체적인 클래스들.
신용카드 결제 방식 클래스
public class CreditCardPayment implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public CreditCardPayment(String name, String cardNumber, String cvv, String dateOfExpiry) {
this.name = name;
this.cardNumber = cardNumber;
this.cvv = cvv;
this.dateOfExpiry = dateOfExpiry;
}
@Override
public void pay(int amount) {
System.out.println(amount + " paid with credit card");
}
}
현금 결제 방식 클래스
public class CashPayment implements PaymentStrategy {
@Override
public void pay(int amount) {
System.out.println(amount + " paid with cash");
}
}
3. 컨텍스트 클래스: 클라이언트가 사용하는 인터페이스를 제공하고 전략 객체를 포함. 구체적인 전략 객체를 설정함.
import java.util.ArrayList;
import java.util.List;
public class ShoppingCart {
private List<Item> items;
private PaymentStrategy paymentStrategy;
public ShoppingCart() {
this.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 setPaymentStrategy(PaymentStrategy paymentStrategy) {
this.paymentStrategy = paymentStrategy;
}
public void checkout() {
int amount = calculateTotal();
paymentStrategy.pay(amount);
}
}
이때 Item 클래스를 추가하고 해당 Item을 내 쇼핑카트에 담아 결제하는 코드를 다음과 같이 구현한다.
public class Item {
private String id;
private int price;
public Item(String id, int price) {
this.id = id;
this.price = price;
}
public String getId() {
return id;
}
public int getPrice() {
return price;
}
}
public class Main {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item item1 = new Item("1234", 10);
Item item2 = new Item("5678", 40);
cart.addItem(item1);
cart.addItem(item2);
// 결제 전략을 신용카드로 설정
cart.setPaymentStrategy(new CreditCardPayment("John Doe", "1234567890123456", "786", "12/15"));
cart.checkout(); // 50 paid with credit card
// 결제 전략을 현금으로 설정
cart.setPaymentStrategy(new CashPayment());
cart.checkout(); // 50 paid with cash
}
}
Strategy Pattern의 장단점
장점
유연성: 알고리즘을 런타임에 변경할 수 있음.
유지보수 용이: 알고리즘이 변경되더라도 클라이언트 코드를 수정할 필요가 없음.
코드 재사용성: 알고리즘을 독립적으로 재사용할 수 있음.
단점
클래스 수 증가: 각 알고리즘을 별도의 클래스로 구현해야 하므로 클래스 수가 증가할 수 있음.
복잡성 증가: 코드 구조가 복잡해질 수 있음.
반응형
'CS > 디자인패턴' 카테고리의 다른 글
[Design Pattern] Decorator Pattern(데코레이터 패턴) (0) | 2024.06.05 |
---|---|
[Design Pattern] Proxy Pattern(프록시 패턴) (0) | 2024.06.03 |
[Design Pattern] Factory Pattern(팩토리 패턴) (0) | 2024.06.01 |
[Design Pattern] Singleton Pattern(싱글톤 패턴) (0) | 2024.05.31 |
[Design Pattern] Builder Pattern(빌더 패턴) (1) | 2024.02.07 |