// 전략 패턴 객체 생성
const strategy = new Strategy();
// {strategy :{}, set(), login()}
strategy.set("email",new EmailAuthcenticator());
// {strategy : {EmailAuthenticator {authentcate}}, set(),login()}
strategy.set("kakao",new KaKaoAuthenticator());
// {strategy : {EmailAuthenticator {authentcate}},{KaKaoAuthenticator {authentcate}}, set(),login()}
strategy.set("google",new Googleauthentiactor());
// {strategy : {EmailAuthenticator {authentcate}},{KaKaoAuthenticator {authentcate}},{Googleauthentiactor {authentcate}}, set(),login()}
// 완성된 객체를 유저 서비스 클래스 생성자의 매개변수로 전달 및 유저 서비스 객체 생성
const userService = new UserService(strategy);
// 유저 로그인 로직 클래스 생성 및 서비스 로직 객체 생성자 매개변수
const userController = new UserController(userService);
userController.signin("kakao");
// 사용자 서비스 로직 클래스 정의
class UserController {
constructor(private readonly userService : UserService){}
// /login/:type
// 위의 경로로 요청이 들어왔을 때 실행할 함수
signin(type :string){
//req.body 유저의 정보를 받아오고
//임시 객체
const loginParams : UserParams = {
email : "ijy@naver.com",
password : "12345"
}
this.userService.login(type, loginParams);
}
// 회원가입
// /signup
signup(){
// 회원가입 로직
}
}
export default UserController
// 유저 서비스 로직 클래스 정의
class UserService {
// 전략패턴 유저 로그인 서비스 로직 객체
// 이메일,카카오,구글 세가지 로그인 로직을 사용할것임
constructor(private readonly strategy : Strategy){}
async login(type : string, credentials : UserParams) : Promise<AuthenticationResponse>{
const result = await this.strategy.login(type,credentials)
return result;
}
}
export default UserService
// 전략 패턴 객체 구조 정의
interface IStrategy {
// key 문자열로 지정
// key가 동적으로 추가될 수 있고
[key : string] : Authenticator
}
// 서비스 로직들을 가질 객체 구조 정의
class Strategy {
private strategy : IStrategy = {}
// 서비스 로직을 객체에 추가할 함수
public set(key : string, authentcate : Authenticator){
// key 값을 받고 서비스 로직 추가
this.strategy[key] = authentcate;
}
public async login(type : string, credentials : UserParams): Promise<AuthenticationResponse>{
const result = await this.strategy[type].authentcate(credentials);
return result
}
}
export default Strategy
export class KaKaoAuthenticator implements Authenticator{
async authentcate(credentials: UserParams): Promise<AuthenticationResponse> {
// 카카오 로그인 로직
return {success : true};
}
}
userController.signin("kakao"); 코드로
this.userService.login(type, loginParams); type 에는 kakao, loginParamas 에는 내가 입력한 정보 객체가 담겨
user.Service.login 함수가 실행된다.
const result = await this.strategy.login(type,credentials) 코드가 실행되게 되는데,
this.strategy에는 index.ts 에서 const strategy = new Strategy(); 와 strategy.set()으로 인해
strategy: {
email: EmailAuthcenticator {},
kakao: KaKaoAuthenticator {},
google: Googleauthentiactor {}
}
인스턴스가 생성되어있고 매개변수에 의해 strategy.ts 의
const result = await this.strategy[type].authentcate(credentials); 코드에
type에는 kakao, credentials 에는 내 객체 정보가 담겨 kakao.strategy.ts 의 클래스가 동작한다.
⭐⭐⭐⭐⭐⭐⭐
이렇게 strategy 패턴으로 코드를 구성하는 이유는
만약 naver 로그인이 추가가 된다고 하면, 같은 형식으로 naver.startegy.ts 를 만들고 set() 함수로 추가만 해주면 된다.
-> 확장성이 용이하다 !