dev_swan 2023. 11. 10. 21:00

✏️ 전략 패턴

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

 

이 패턴은 특정 작업을 수행하기 위한 다양한 알고리즘을 준비하고 필요에 따라 선택적으로 교체하는 데 유용합니다. 주로 알고리즘을 동적으로 선택하고 변경해야 할 때 활용됩니다.

Strategy Pattern - https://sourcemaking.com/design_patterns/strategy

 

💻 자바스크립트의 전략 패턴

class ConcreteStrategyA {
    doSomething() {
        console.log('StrategyA');
    }
}

class ConcreteStrategyB {
    doSomething() {
        console.log('StrategyB');
    }
}

class Context {
    constructor() {
        this.strategy = null;
    }

    setStrategy(strategy) {
        this.strategy = strategy;
    }

    doSomething() {
        this.strategy.doSomething();
    }
}

const strategy = new Context();

strategy.setStrategy(new ConcreteStrategyA());
strategy.doSomething(); // StrategyA

strategy.setStrategy(new ConcreteStrategyB());
strategy.doSomething(); // StrategyB

전략을 추상화하는 인터페이스 ConcreteStrategyA와 ConcreteStrategyB는 특정 작업을 위한 알고리즘을 구체적으로 구현합니다.

 

Context 클래스는 전략 인터페이스를 변경하는 역할을 합니다. setStrategy 메서드를 통해 현재 전략을 변경하고, doSomething 메서드를 호출하여 선택된 전략을 실행하게 됩니다.

 

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

 

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

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

passport.use(
    new LocalStrategy(function (username, password, done) {
        User.findOne({ username }),
            function (error, user) {
                if (error) {
                    return done(error);
                }
                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 메서드에 전략을 매개 변수로 넣어서 로직을 수행하는 것을 볼 수 있습니다.


👍 전략 패턴의 장점

전략 패턴은 코드 재사용과 유지보수를 개선하는 데 도움이 됩니다. 새로운 전략이 필요한 경우 새로운 전략 클래스만 작성하면 되며, 기존 코드에 영향을 미치지 않습니다. 또한 코드의 가독성과 유연성을 높이는 데 도움이 됩니다.