본문 바로가기
CS

전략 패턴

by Shark_상어 2023. 1. 21.
728x90

전략 패턴

전략 패턴(strategy pattern)은 정책 패턴(policy pattern)이라고도 하며, 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않는다.

전략 이라고 부르는 '캡슐화한 알고리즘'을 컨텍스트안에서 바꿔 주면서 상호 교체가 가능하게 만드는 패턴이다.

우리가 어떤 것을 살 때 네이버페이, 카카오페이 등 다양한 방법으로 결제하듯이 어떤 아이템을 살 때 LUNACard로 사는 것과 KAKAOCard로 사는 것을 구현한 예제이다.

결제 방식의 '전략'만 바꿔서 두 가지 방식으로 결제하는 것을 구현한 것이다.

import java.io.DecimalFormat;
import java.util.ArrayList;
import java.util.List;

interface PaymentStrategy {
    public vodi 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.cost = cost;
    }
    
    public String getName() {
        return name;
    }
    
    public String 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 Helloworld {
    public staic void main(String[] args) {
        ShoppingCart cart = new ShoppingCart();
        
        Item A = new Item("kundolA", 100);
        Item B = new Item("kundolB", 300);
        
        card.addItem(A);
        card.addItem(B);
        
        cart.pay(new LUNACardStrategy("kundol@example.com", "pukubababo"));
        
        cart.pay(new KAKAOCardStrategy("JU hongchul", "123456789", "123", "12/01"));
    }
}

/*
400 paid using LUNACard.
400 paid using KAKAOCard.
*/

 

위의 코드는 쇼핑 카트에 아이템을 담아 LUNACard 또는 KAKAOCard라는 두 개의 전략으로 결제하는 코드이다.

passport의 전략 패턴

전략 패턴을 활용한 라이브러리로는 passport가 있다.

passport는 Node.js에서 인증 모듈을 구현할 때 쓰는 미들웨어 라이브러리로, 여러 가지 ‘전략’을 기반으로 인증할 수 있게 한다.

서비스 내의 회원가입된 아이디와 비밀번호를 기반으로 인증하는 LocalStrategy 전략과 페이스북, 네이버 등 다른 서비스

를 기반으로 인증하는 OAuth 전략 등을 지원한다.

다음 코드처럼 ‘전략’만 바꿔서 인증하는 것을 볼 수 있다.

var passport = require('passport')
    , LocalStrategy = require('passport-local').Strategy;

passport.use(new LocalStrategy(
    function(username, password, done) {
        User.findOne({ username: username }, function (err, user) {
          if (err) { return done(err); }
            if (!user) {
                return done(null, false, { message: 'Incorrect username.' });
            }
            if (!user.validPassword(password)) {
                return done(null, false, { message: 'Incorrect password.' });
            }
            return done(null, user);
        });
    }
));

passport.use(new LocalStrategy( ...처럼 passport.use()라는 메서드에 ‘전략’을 매개변수로 넣어서 로직을 수행하는 것을 볼 수 있다.

728x90

'CS' 카테고리의 다른 글

프록시 패턴 과 프록시 서버  (0) 2023.01.24
옵저버 패턴  (0) 2023.01.23
팩토리 패턴  (0) 2023.01.20
디자인 패턴 - 싱글톤 패턴  (0) 2023.01.18
CPU 스케줄링 알고리즘  (0) 2023.01.16