https://thebook.io/080326/0017/
1. 전략패턴의 정의
2. 전략패턴 구현
3. 전략패턴의 장점
4. 전략패턴의 사용
5. 전략패턴의 단점
6. 전략패턴과 팩토리패턴의 차이점
전략패턴(Strategy pattern)은 정책 패턴(Policy pattern)이라고도 하며, 객체의 행위를 바꾸고 싶은 경우, 직접 수정 없이도 전략이라고 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주며 상호 교체가 가능하게 만드는 패턴
컨텍스트 : 상황, 맥락, 문맥을 의미. 개발자가 어떤 작업을 완료하는데 필요한 모든 관련 정보
간략하게 하자면,행위를 클래스로 캡슐화해, 동적으로 행위를 자유롭게 바꿀 수 있게 해주는 패턴
GoF 디자인 패턴에서는 행동
및 객체
분류에 해당한다. 행동
패턴은 객체가 상호작용하는 방법이나 관심사를 분리하는 방법에 관여한다.
interface PaymentStrategy {
public void pay(int amount);
}
class KAKAOCardStrategy implements PaymentStrategy {
private String name;
private String cardNumber;
private String cvv;
private String dateOfExpiry;
public KAKAOCardStrategy(String nm, String ccNum, String cvv, String expiryDate {
this.name = nm;
this.cardNumber = ccNum;
this.cvv = cvv;
this.dataOfExpiry = expiryDate;
}
@Override
public void pay(int amount) {
System.out.println("KAKAOCARD " + amount);
}
}
class APPLECardStrategy implements PaymentStrategy {
private String emailId;
private String password;
public APPLECardStrategy(String email, String pw) {
this.emailId = email;
this.password = pw;
}
@Override
public void pay(int amount) {
System.out.println("APPLECARD " + amount);
}
}
class Item {
private String name;
private int price;
public Item(String name, int cost) {
this.name = name;
this.price = cost;
}
public String getName() {
return name;
}
public int getPrice() {
return price;
}
}
class ShoppingCart {
List<Item> items;
public ShoppingCart() {
this.items = new ArrayList<Item>();
}
public void addItem(Item item) {
this.items.add(item);
}
public void removeItem(Item item) {
this.items.remove(item);
}
public int calculTotal() {
int sum = 0;
for (Item item : items} {
sum += item.getPrice();
}
return sum;
}
public void pay(PaymentStrategy paymentMethod) {
int amount = calculTotal();
paymentMethod.pay(amount);
}
}
public class HelloWorld {
public static void main(String[] args) {
ShoppingCart cart = new ShoppingCart();
Item A = new Item("a", 100);
Item B = new Item("b", 300);
cart.addItem(A);
cart.addItem(B);
cart.pay(new KAKAOCardStrategy("BBB", "000011112", "123", "08/31");
cart.pay(new APPLECardStrategy("BBB@example.com", "1111");
}
}
/// KAKAOCARD 400
/// APPLECARD 400
상황에 따라 사용할 알고리즘 교환이 쉽다
알고리즘 구현 / 사용이 분리되어 있다 = 각각 목적에 따라 구현을 다르게 할 수 있다. 그래서 알고리즘 특정 데이터에만 집중하면서 새로운 기능 구현(Strategy)를 추가하기 쉽다
상황에 따라 사용해야할 알고리즘을 클라이언트가 정해야할 때 (게임 같은 곳에서 상황에 따라 아이템 등을 바꿔야할 때 처럼)
동일 계열의 알고리즘들을 인터페이스로 통일하여 제공해야할 때
왜 사용할까?
동물로 예시 설명
공통된 인터페이스(Strategy)를 정의하고, 그에 Concrete Strategy를 구현함. 이를 사용 클래스(Context)에서 사용하게 되면, 계속되는 상속의 상속 문제나 중복 코드 발생을 해결할 수 있다.
알고리즘 (Strategy) 수 만큼 전체 객체 수가 증가
이전에 팩토리패턴에 대해서 알아봤는데 유사하다고 느꼈다.
그래서 헷갈리다고 느껴서 뭐가 다른가 공부중 해당 링크 발견
팩토리 디자인 패턴은
생성 디자인 패턴
으로, 객체를 만드는 가장 좋은 방법 중 하나. 해당 패턴은 팩토리 메서드를 사용하여 객체의 정확한 클래스를 정의하지 않고, 객체 생성 문제를 처리합니다.
전략 패턴은 어떤 특정 알고리즘을 런타임시 변경하고 싶을 때, Context
에 전략 사용을 위한 인터페이스 reference
를 저장하고 동작 요청 (strategy 에서 concrete strategy를 변경한다는 의미)
중요한 점은 Reference를 저장할 때, 특정 전략에 대한 객체에 대해 new를 통해 객체를 생성하고 context에 저장된 객체 정보를 바탕으로 알고리즘을 수행합니다.
팩토리패턴은 객체를 생성하기 위한 인터페이스를 정의하는데, 어떤 클래스의 객체를 만들지는 서브클래스에서 결정됩니다. 그래서 부모클래스에서 직접적으로 new를 통해 생성하지 않아도 된다는 것입니다.