TypeScript 전략패턴 폴더 세분화

이재영·2023년 9월 3일
0

TypeScript

목록 보기
3/3
post-thumbnail

index.ts

// 전략 패턴 객체 생성
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");

user.controller.ts

// 사용자 서비스 로직 클래스 정의
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

user.service.ts

// 유저 서비스 로직 클래스 정의
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

strategy.ts

// 전략 패턴 객체 구조 정의
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

kakao.strategy.ts

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() 함수로 추가만 해주면 된다.
-> 확장성이 용이하다 !

profile
한걸음씩

0개의 댓글

Powered by GraphCDN, the GraphQL CDN