전략패턴

HS K·2023년 2월 15일
0
post-custom-banner

전략패턴

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

실제 라이브러리로는 인증모듈에 쓰이는 passport가 있다.

  • 소셜로그인때 쓰인다.

※ 컨텍스트 : 프로그래밍에서 상황, 맥락, 문맥을 의미하고 개발자가 어떤 작업을 완료하는데 필요한 관련된 모든 정보를 말한다.

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);
    } //앞에서 만든 strategy가 담겨서 Override된 method로 구동이 되어서 지불되는 것을 알 수 있다. 
}
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.
*/
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); });

cart.pay()

cart라는 형이 유지가 되지만

cart.pay(new LUNACardStrategy("kundol@gmail.com", "pukubabo"));

인자들만 strategy로 캡슐화하여 넣으면 로직을 짤때 쉬워진다.


부록 - 프로그래밍 컨텍스트

컨텍스트

  1. 어떤 종류의 상태, 환경을 캡슐화한 것을 말함.
  2. 작업이 중단 되고 나중에 같은 지점에서 계속 될 수 있도록 저장하는 최소 데이터 집합.(컨텍스트스위칭)

컨텍스트는 context와 contextual information으로 크게 나눠지는데 다음과 같습니다.
1. 병원에 가면 “이름”과 주민등록번호 앞자리를 말해야죠? 자 여기서 “병원에
방문”하는 context에서 여러분의 이름은 contextual information이 됩니다.
2. HTTP요청을 하는 context에서 HTTP Header는 contextual inforamation이라고 할
수 있음.
3. 트랜잭션이라는 context에서 트랜잭션 ID가 contextual information 이라고 할 수
있습니다.
이러한 이론을 기반으로 한 다양한 모듈 또는 API로는 react.js에서는 전역적으로 “상태”값을 넘길 수 있는 context API가 있습니다.

const ThemeContext = React.createContext('light');
class App extends React.Component {
    render() {
        return ( 
          <ThemeContext.Provider value = "dark" >
            <Toolbar / > < /ThemeContext.Provider>
        );
    }
}

function Toolbar() {
    return (
      <div > 
            < ThemedButton />
      </div> 
    );
}

class ThemedButton extends React.Component {
  static contextType = ThemeContext;
  render() {
     return <Button theme = {this.context} />; 
  }
}

React에서 context API를 통해 전역적으로 static contextType을 통해 상태관리를 하는 모습.

profile
주의사항 : 최대한 정확하게 작성하려고 하지만, 틀릴내용이 있을 수도 있으니 유의!
post-custom-banner

0개의 댓글