이터레이터 패턴 / 전략 패턴

JoyJuhee·2022년 7월 6일
0

디자인 패턴

목록 보기
3/5
post-thumbnail

1. 이터레이터 패턴

이터레이터 패턴(iterator pattern) : 이터레이터를 사용하여 컬렉션의 요소들에 접근하는 디자인 패턴

컬렉션 = 컨테이너라고도 하고, 동일한 요소들의 집합(배열, 트리 등)
이터러블한 객체 = 반복 가능한 객체로 배열을 일반화한 객체
이터레이터 프로토콜 = 이터러블한 객체들을 순회할 때 쓰이는 규칙

👉 순회할 수 있는 각기 다른 자료형의 구조와는 상관없이 이터레이터라는 하나의 인터페이스로 순회가 가능해서 코드의 효율화, 숫자형 index가 아닌 string들 다양한 인덱스를 기반으로 순회를 쉽게 할 수 있음.

📍 자바 스크립트 예시

const mp = new Map() 
mp.set('a', 1)
mp.set('b', 2)
mp.set('cccc', 3) 
const st = new Set() 
st.add(1)
st.add(2)
st.add(3) 
const a = []
for(let i = 0; i < 10; i++)a.push(i)

for(let aa of a) console.log(aa)
for(let a of mp) console.log(a)
for(let a of st) console.log(a) 
/* 
a, b, c 
[ 'a', 1 ]
[ 'b', 2 ]
[ 'c', 3 ]
1
2
3
*/

2. 전략 패턴(strategy pattern)

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

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의 전략패턴

  • 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);
        });
    }
));

📍 의존성주입과 전략패턴의 차이

  • 의존성주입이나 전략패턴 모두 "무언가를 쉽게 교체하기 위한 디자인패턴"이고, 같은 방식으로 작동한다.

  • 전략패턴 : 의도에 초점을 맞추고 동일한 행동 계약(결제, 인증 등)을 준수하는 다양한 구현(전략)으로 인터페이스를 만들도록 권장하는 것을 포함

  • 의존성주입 : 단지 일부 동작을 구현하고 의존성을 주입하기만 하는 패턴

📍 강의를 듣다가 전략패턴이 의존성주입에 포함되는 의미인지, 즉 의존성주입이 더 넓은 의미라고 이해해도 되는지 의문이 생겨 질문을 남겼다.
--> 강사님께서 답변을 남겨주셨다.

결론은 전략패턴과 의존성주입은 각자 다른 디자인 패턴으로 이해해야한다는것!

출처 : [책]면접을 위한 CS 전공지식 노트

0개의 댓글