전략 패턴
공통된 기능을 인터페이스 중심으로 기능을 들어내서 의존성을 주입한다.
클래스로 생성 객체를 기능으로 받아서 사용하는 패턴 클래스를 공통된 기능 단위로 작성한다.
상속을 받을 경우에는 공통된 기능을 조건문으로 다 처리를 해야하는데
기능의 의존성을 공유하지 않고 하나의 기능만 관리하게 공통된 기능단위로 클래스를 작성한다.
(확장성 + 유지보수성 증가)
// interface
// 유저가 전달할 데이터 객체 구조 정의
interface IUserParams{
email : string;
password : string;
}
// 유저가 로그인을 요청하고 응답을 받았을 때
// 유니온 : 타입을 두가지 이상 포함 시킬 수 있다.
interface IAuthReps{
success : boolean;
// message 키가 있어도 되고 없어도 된다.
message? : string | Error;
}
// 검증 객체 구조 정의
interface IAuth {
// 로그인 검증을 하는 함수를 공통으로 주고
authenticate(credentials : IUserParams) : IAuthReps;
}
// 전략 패턴 객체 구조 정의
interface IStrategy {
// key 문자열로 작성
// 포함시킬 기능이 생길 때마다 키를 추가하면서 값을 넣어줄 것
[key : string] : IAuth;
}
////////////// strategy /////////////////
class Strategy {
private strategy : IStrategy = {};
// 서비스 로직을 객체에 추가할 함수
// 의존성 주입을 할 부분
setStrategy(key : string, authenticate : IAuth){
// key 값을 받아서 key 추가하면서 로직 추가
this.strategy[key] = authenticate;
}
login(type : string, credentials : IUserParams) : IAuthReps {
const result = this.strategy[type].authenticate(credentials);
return result;
}
}
//////////// auth /////////////////
// 이메일 로그인 검증 클래스 정의
class EmailAuth implements IAuth {
authenticate(credentials : IUserParams) : IAuthReps {
// credentials === 유저가 입력한 값
// 조건문을 credentials 값으로 작성
// 이메일 로직 부분 작성
console.log("email 로그인 성공");
// 성공 객체 반환
return { success : true, message : "이메일 로그인 성공" }
}
}
// 구글 로그인 검증 클래스 정의
class Google implements IAuth {
authenticate(credentials : IUserParams) : IAuthReps{
// 구글 로그인 로직 부분 작성
console.log("google 로그인 실패");
// Error : 객체를 만들어 준다.
// 생성자에서 매개변수로 전달한 문자열을 가지고 객체를 생성한다.
return { success : false, message : new Error("구글 로그인에서 에러 발생") };
}
}
// 카카오 로그인 검증 클래스 정의
class KakaoAuth implements IAuth{
authenticate(credentials : IUserParams): IAuthReps{
// 카카오 로그인 로직 부분 작성
console.log("kakao 로그인 성공");
return { success : true };
}
}
////////// servie ////////////
class UserService{
// 서비스들 기능들을 구조로 정의할 클래스
// readonly 값을 읽기만 가능하고 수정할 수 없다.
// 생성자 매개변수로 private readonly 매개변수명까지 넣고 생성자를 호출하게 되면
// 키값은 strategy 전달한 매개변수로 객체에 키가 추가된다.
constructor(private readonly strategy : Strategy){}
login(type : string, credentials : IUserParams) : IAuthReps{
const result = this.stategy.login(type, credentials);
return result;
}
}
///////// controller ///////////
// 유저 서비스 로직 실행 클래스 정의
class UserController {
constructor(private readonly UserService : UserService){}
signin (type : string) {
const loginParams : IUserParams = {
email : "jaka@naver.com",
password : "123456"
}
const result = this.UserService.login(type, loginParams);
console.log(result);
}
}
// 전략 패턴 객체 생성
const strategy = new Strategy();
// 로그인 로직을 추가
strategy.setStrategy("email", new EmailAuth());
// 카카오 로그인 로직 추가
strategy.setStrategy("kakao", new KakaoAuth());
// 구글 로그인 로직 추가
strategy.setStrategy("google", new GoogleAuth());
// 완성된 전략 패턴의 객체를 userservice 객체에 전달해서 생성
const userService = new UserService(strategy);
// 유저가 로그인 로직을 실행할 클래스 생성 userController
const userController = new UserController(userService);
// 유저가 로그인을 시도했다.
userController.signin("kakao");
userController.signin("google");
userController.signin("email");
'Typescript' 카테고리의 다른 글
[TS] 타입 어서션 / 타입 앨리어스 / 클래스 수정자 / 제네릭 (0) | 2024.04.29 |
---|---|
[TS] interface & class (0) | 2024.04.24 |
[TS] Typescript 첫시작 (0) | 2024.04.23 |