티스토리 뷰

728x90

전략 패턴(strategy pattern)

개념

- 정책 패턴(policy pattern)이라고도 함

- 객체의 행위를 바꾸고 싶은 경우 직접 수정하지 않고 캡슐화한 알고리즘을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴

 

장점

- 컨텍스트 코드의 변경 없이 새로운 전략 추가 가능

더보기

컨텍스트란?

- 개발자가 어떠한 작업을 완료하는 데 필요한 모든 관련 정보(상황, 맥락, 문맥)

- 요구사항이 변경되었을 때 기존의 코드를 변경하지 않아도 됨

- 새로운 전략에 대해서는 새로운 클래스를 통해 관리하므로 OCP의 원칙을 준수할 수 있음

 

단점

- 컨텍스트에 적용되는 알고리즘이 하나이거나 두 개인 경우에는 분기를 활용하는 것이 용이할 수도 있음

- 요구사항의 변경으로 변경될 여지가 있으며, 변화의 형태가 다양하면 전략 패턴을 고려해보면 좋음

 

코드

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 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 + " paid using KAKAOCard.");
    }
}

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

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

    @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 price) {
        this.name = name;
        this.price = price;
    }

    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 Hello {
    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);

        // LUNA Card
        cart.pay(new LUNACardStrategy("sa11k@tistory.com", "sa11k"));

        // KAKAO Card
        cart.pay(new KAKAOCardStrategy("sa11k", "123456789", "123", "07/22"));
    }
}

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

 

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);
        });
    }
});
728x90
댓글
공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday