전략 패턴

전략 패턴(strategy pattern) 또는 정책 패턴(policy pattern)은 실행 중에 알고리즘을 선택할 수 있게 하는 행위 소프트웨어 디자인 패턴이다. [출처: 위키피디아]

객체의 행위를 바꾸는 것이 아닌, 전략이라고 부르는 캡슐화된 알고리즘을 바꿔주면서 상호 교체가 가능하게 만드는 패턴

언제 쓰나요?

어떤 동작을 수행하는 알고리즘 혹은 전략이 여러 가지일 때, 이러한 알고리즘의 변형이 자주 일어나는 경우에 적합하다. ex) 결제

image

결제라는 행위는 같지만 그 안에서 어떤 식으로 결제할지 상호 교체가 가능하도록 하기 위해 사용.

또는 내부 알고리즘 코드를 캡슐화하는 용도로 사용될 수도 있다. 전략으로 불리는 내부 로직을 직접 보여주지 않고 호출하여 사용하기 때문.

주의할 점

  • 해당 전략을 런타임 시에 결정하기 위해서 개발자는 모든 로직에 대해 정확하게 알고 차이점을 파악하고 있어야 한다.

코드

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.List;
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.dateOfExpiry=expiryDate;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount +" paid using KAKAOCard.");
    }
}

class LUNACardStrategy implements PaymentStrategy {
    private String emailId;
    private String password;

    public LUNACardStrategy(String email, String pwd){
        this.emailId=email;
        this.password=pwd;
    }

    @Override
    public void pay(int amount) {
        System.out.println(amount + " paid using LUNACard.");
    }
}

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 calculateTotal(){
        int sum = 0;
        for(Item item : items){
            sum += item.getPrice();
        }
        return sum;
    }

    public void pay(PaymentStrategy paymentMethod){
        int amount = calculateTotal();
        paymentMethod.pay(amount);
    }
}
public class Strategy{
    public static void main(String []args){
        ShoppingCart cart = new ShoppingCart();

        Item A = new Item("kundolA",100);
        Item B = new Item("kundolB",300);

        cart.addItem(A);
        cart.addItem(B);

        // pay by LUNACard
        cart.pay(new LUNACardStrategy("kundol@example.com", "pukubababo"));
        // pay by KAKAOBank
        cart.pay(new KAKAOCardStrategy("Ju hongchul", "123456789", "123", "12/01"));
    }
}
/*
400 paid using LUNACard.
400 paid using KAKAOCard.
*/

해당 코드에서는 “결제”라는 행위를 카카오 혹은 LUNA카드라는 두 가지 행위로 나누어서 진행한다. cart에 담은 물건들을 결제할 때에 결제 전략을 선택하여 cart.pay(new LUNACardStrategy("kundol@example.com", "pukubababo"));와 같은 형식으로 실행한다.

참고

참고 도서 - 면접을 위한 CS 전공지식 노트 Inpa Dev: 전략(Strategy) 패턴 - 완벽 마스터하기

Leave a comment