전략 패턴은 정책 패턴이라고도 하며, 객체의 행위를 바꾸고 싶은 경우 '직접' 수정하지 않고
전략이라고 부르는 '캡슐화한 알고리즘'을 컨텍스트 안에서 바꿔주면서 상호 교체가 가능하게 만드는 패턴
컨텍스트
- 프로그래밍에서의 컨텍스트는 상황, 맥락, 문맥을 의미하며 개발자가 어떠한 작업을 완료하는 데 필요한 모든 관련 정보를 말한다
1. 자바의 전략 패턴
- 어떤 것을 살 때 네이버페이, 카카오페이 등 다양한 방법으로 결제하듯이 어떤 아이템을 살 때 LUNACard로 사는 것과 KAKAOCard로 사는 것을 구현한 예제
- 결제 방식의 '전략'만 바꿔서 두 가지 방식으로 결제하는것 구현
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 HelloWorld{
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.
*/
2. 자바스크립트의 전략 패턴 - 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()라는 메서드에 '전략'을 매개변수로 넣어서 로직을 수행
3. 예상 질문
✏️ 1. 전략 패턴이 무엇인가요?
- 전략 패턴은 행동(알고리즘)을 캡슐화하고, 이를 동적으로 교체할 수 있도록 하는 디자인 패턴입니다.
- 전략 패턴은 컨텍스트(Context), 전략(Strategy), 전략 인터페이스(Strategy Interface)로 구성됩니다.
- 하나의 예시로 정렬 알고리즘을 선택하여 실행하는 정렬 프로그램이 있다고 할 때, 각 정렬 알고리즘을 전략으로 구현하고, 런타임에 선택한 정략을 사용할 수 있습니다.
✏️ 2. 그럼 전략 패턴은 왜 사용하나요?
- 전략패턴은 객체의 동작을 동적으로 변경하고 확장하기 위해 사용합니다.
- 또한 새로운 전략을 추가하거나 기존 전략을 변경할 때, 컨텍스트 클래스를 수정하지 않아도 되므로 코드의 유지보수성이 향상됩니다.