전략 패턴

공통된 기능을 인터페이스 중심으로 기능을 들어내서 의존성을 주입한다.

클래스로 생성 객체를 기능으로 받아서 사용하는 패턴 클래스를 공통된 기능 단위로 작성한다.

상속을 받을 경우에는 공통된 기능을 조건문으로 다 처리를 해야하는데

기능의 의존성을 공유하지 않고 하나의 기능만 관리하게 공통된 기능단위로 클래스를 작성한다.

(확장성 + 유지보수성 증가)

 

// 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");

목차

1. 타입 어서션

2. 타입 앨리어스

3. 타입 클래스 수정자

4. 제네릭

 

1. 타입 어서션

구체적인 객체의 타입을 알려주고 명시한다.

변수명 = 값 as 타입

ex)
const input = document.querySelector("input");
// 자바스크립트 경우에서는 에러가 발생하지 않는다.

const input = documnet.querySelector("input") as HTMLinputElemnet
// typescript에서는 input에 as 타입을 지정해 주어야 에러가 발생하지 않는다

 

 

2. 타입 앨리어스

- 타입 지정에 별명을 붙여줄  때 사용합니다.

ininterface기능이나 사물의 객체의 구조를 정의할 때 사용하고

type데이터의 형태를 정의할 때 사용합니다.

type userLogin = {
    uid : string,
    upw : string
}

 

 

3. 타입 클래수정자

class User {
    private name : string; 
    // private 은 객체를 생성하고 점표기법, 대괄호표기법으로 접근이 불가능하다. 직접 참조할 수 없게 만든다.
    // 다른 작업자나 아니면 혹여나 의도치 않게 변경될 경우를 고려하여 직접 참조 혹은 수정이 불가능하다.
    // 객체 안에서는 수정이 가능하다.

    public age : number;
    // public 은 객체도 참조 수정이 가능하고 점표기법, 대괄호표기법 접근이 가능하다.
    // 유저를 관리하거나 하다 보면 값을 풀어야 하는 상황이 생기기도 한다. (객체지향적으로 프로그래밍을 하다가          어쩔 수 없을 때)

    // get set
    getName (){
        // private 속성은 객체 안에서 메서드로 this를 참조하여 호출할 수 있다.
        return this.name;
    }

     setName (_name){
        // privatge 속성에 접근해서 name의 값을 수정
           this.name = _name;
    }
}

 

4. 제네릭 타입

호출시에 동적인 타입을 주고 싶은 경우에 사용

<T> :  제네릭 타입 문법

타입을 전달한다.

class User<A> {
    private name : A[] =[];
}
const user = User<string>();

// 제네릭을 사용하는 목적은 코드의 재사용성을 높히기 위해서
const product = Product<number>();
const product = Product<string>();

// T : 타입의 축약어 , E : Error의 타입 , R : 변환타입
function name<T, R>(name : T):R{
    return parseInt(name + 1);
}
name<string, number>();
const user = userLogin ={
    uid,
    upw
}
name<userLogin, boolean>(user)

 

 

'Typescript' 카테고리의 다른 글

[TS] 전략패턴  (0) 2024.05.02
[TS] interface & class  (0) 2024.04.24
[TS] Typescript 첫시작  (0) 2024.04.23

 

목차

1. interface란?

2. interface 사용

3. 선택적 프로퍼티

4. 읽기 전용 프로퍼티

5. 인터페이스 클래스 타입

 

1. interface란?

타입스크립트에서 인터페이스는 두시스템 사이에 상호간에 정의한 통신규약이며 선언만 존재합니다. 타입을 미리 선언해주는 장치로서 사용할 수 있다. 미리 개발할 때 서로 공통적으로 사용할 부분을 미리 선언을 할 때 사용한다. 사용목적은 클래스와 함수간의 일관성을 유지할 수 있도록 하기 위함이다.

 

2.interface 특징

- ES6(자바스크립트)가 지원하지 않는 TypeScript 에서만 사용

- 컴파일 후에 사라진다 (자바스크립트에서 지원하지 않기 문이다)

- interface 간에 다중상속이 가능

 

interface  예시

// 인터페이스명은 대문자로 표기
interface IUser {
  name: string; // name 문자열
  age: number; // age 숫자
  fn1() : void; // fn1은 void 타입
}

// 인터페이스 자체를 타입으로 줘서 객체 생성
const user : IUser = {
  name : "Jaka",
  age : 33,
  fn1: ()=> {console.log("Hello World")};
};

// 매개변수를 인터페이스 타입으로 받기
function fn1(a: IUser): void{
  console.log(`${a.name} 은 ${a.age}살이야.`)
};

fn1(user); // jaka는 33살이야
person.fn1(); // Hello World

 

3. 선택적 프로퍼티 (Optional Properties)

인터페이스에 있는 속성을 다 사용해야 한다면 코드의 유연성이 사라질 수 있다. 이를 해결하기 위한 방법으로 우리는 선택적 프로퍼티라는 것을 사용할 수 있다. 문법은 (:) 전에 '?'를 넣어주면 된다. 아래의 코드로 예제를 보자

interface ICoffee {
  name : string;
  flavor?: string;
}

function orderCoffee(coffee: ICoffee){
  consolel.log(coffee.name);
}

let myCoffee = { name : "latte" }; // flavor는 명시 안함 
orderCoffee(myCoffee); // latte
interface ICustomer {
  name : string;
  age : number;
  tel? : string;
}

let customer : ICustomer = {
  name : "jaka",
  age : 30
}

customer.name = "jaka2";
customer.tel = "123-4567"; // 선택적 프로퍼티가 있으면 값을 나중에 추가할 수 있다.
customer.address = "서울"; // 정의되지 않은 속성을 마음대로 넣을수는 없음

 

4. 읽기 전용 프로퍼티 (readonly)

readonly는 인터페이스로 객체를 처음 생성할 때만 값을 할당하고 그 이후에는 변경할 수 없는 속성을 의미한다. 변하지 않는 값 const와 비슷하다고 생각하면 된다. 다음 예제를 보자.

interface Book {
  title : string;
  year : number;
  readonly writer : string; // 읽기 속성 전용
}

let book : Book = {
  title : "콩쥐팥쥐",
  year : 2002,
  writer : "김철수"
};

book.writer = "철수"; // Error 이후에는 수정이 불가능

 

5. 인터페이스 클래스 타입

인터페이스로 클래스를 정의하는 경우, implemets를 사용하면 된다.

interface IUser {
  name : string;
  getName() : string;
}

// IUser 인터페이스를 Implements 하면 User 클래스의 프로퍼티 구조는 반드시 IUser에 정의 된대로 따라야한다.
// 즉, 반드시 name, getNmae() 클래스에 기본값으로 구현해야 한다

class User implements IUser {
  name: string;
  
  constructor(name: string){
    this.name = name;
  }
  
  getName() {
    return this.name;
  }
}

const jaka = new User("jaka");
jaka.getName(); // jaka

'Typescript' 카테고리의 다른 글

[TS] 전략패턴  (0) 2024.05.02
[TS] 타입 어서션 / 타입 앨리어스 / 클래스 수정자 / 제네릭  (0) 2024.04.29
[TS] Typescript 첫시작  (0) 2024.04.23

GUI (Grahpoic User Interface) : 볼 수 있는 아이콘등의 UI가 있는 것

CLI (Command Line Interface) : 콘솔창을 통해서 프로그램을 실행하는 환경

- CLI 는 터미널을 통해 컴퓨터가 상호작용을 하는 방식

- 유저는 문자열의 형태로 작성해서 컴퓨터에게 출력을 받는다

 

터미널을 사용하기 위해 키보드 입력같은 명령어를 실행하고 폴더와 파일 등을 관리합니다.

명령어를 입력하면 커널이 읽을 수 있는 이진코드로 변환합니다.

 

커널

컴퓨터를 켜면 메모리에 항상 올라가 있는 운영체제.

하드웨어와 프로그램 사이에서 인터페이스를 제공하는 역할을 담당합니다.

컴퓨터의 자원들을 관리하는 역할을 합니다.

cd : 하위 폴더 경로로 이동
cd.. : 상위 폴더 경로로 이동

 

 

npm

node의 패키지 매니저

다른 개발자들이 만든 코드를 폴더로 만들어서 배포를 한 파일을 다른 개발자들이 받아서

이어서 작업할 수 있게 나이가 많은 프로그램들을 다시 만들 필요 없이 가져와서 사용한다.

 

npm이란

- 명령줄 클라이언트 공개방식들과 지불 방식들의 패키지를 설치할 수 있습니다.

- 개발자들이 자신이 작성한 모듈 등등을 공유할 수 있는 저장소를 npm을 활용하여 쉽게 설치 

 받을 수 있습니다. 

- 오픈소스 생태계를 구축하기 위함과 개발 생산성을 향상하기 위함입니다.

npm init
# package.json 초기화 --> 설치 받은 라이브러리가 여기에 나와요!

npm init -y #바로 초기화

# 패키지를 설치하는 명령어
npm install [패키지명] 
npm i [패키지]

# 개발 환경에서 설치할건지
npm install --save-dev [패키지명]

# 개발환경에서만 사용할 패키지
npm i -D [패키지명]

# 전역으로 패키지 설치
npm i -g [패키지명]

# npm 패키지 설치 package.json에 있는 내용을 가지고
npm i

 

package.json

- 우리가 작업하는 패키지의 정보와 설치한 라이브러리의 이름과 정보를 가지고 있습니다.

- npm으로 명령어를 실행하는 경우 읽어서 실행하는 json 파일

typescript 패키지를 설치한 내용을 기록이 패키지에서
무엇 무엇을 사용했는지`의존성 모듈`
"dependencies": {    "typescript": "^5.4.5"  }-- ^: 버젼이 없으면 이후 버젼을 설치해야한다

 

tsconfig.json 

컴파일을 진행할 때 검사의 속성이나 파일의 경로 속성을 정의하는 json 파일

# typescript의 json도 따로 설치를 해서 컴파일 옵션을 설정한다.
# typescript 설치

# 설치
npm install typescript
npm i typescript

# 제거
npm uninstall typescript

# 설치가 잘 되어 있는지 버전을 확인
# npx 실행할 때 사용
# tsc 타입스크립트 명령어
# tsc 컴파일 진행

npx tsc --init

# 컴파일 진행
npx tsc

 

include : 컴파일을 진행할 폴더 지정
exclude : 제외할 폴더 지정

compilerOptions 속성에 포함
target : 변환파일의 es버전 ES5로 만들건지 ES6으로 만들건지 결정
outDir : 변환된 파일을 내보낼 경로를 지정

 

{
    // 와일드 카드
    // css *
    // /* : 모든 파일을 포함한다.
    // /** : 모든 폴더를 포함시키겠다.
    // src 폴더에 모든 폴더들에서 모든 파일을 포함 시키겠다
    
    // **/.test.ts : 현재 폴더에서 모든 폴더의 파일중에서 확장자로
    // .test.ts 라고 작성된 파일을 컴파일에서 제외시키겠다
    
    "include":[
        "src/**/*"
    ],
    "exclude":[
        "**/*.test.ts"
    ],
    "compilerOptions":{
        "target": "ES6",
        "outDir": "./dist", // 정하는 이름
        "removeComments": true // 주석을 제거해서 변환하겠다
    }
}

 

 

타입 스크립트

javascript에서 타입 검사가 추가된 확장 언어라고 생각하면 된다.

 

typescript는 javascript의 슈퍼셋

- typescript는 javascript와 다르게 런타임 환경이 존재하지 않습니다.

- 컴파일 언어(컴파일러가 존재)

- typescript -> javascript 로 변환

- 코드 실행은 자바스크립트로 합니다. 

- 코드 작성단계에서 의도에 맞지 않게 코드를 작성한 경우에도 오류를 표시합니다.

 

문법

// 예약어 변수명 : 타입명 = 초기값
// any타입 뭐든 가능한 타입

let num : number = 20;
const str : string = "typescript";
const nan : number = NaN;
const _null : null = null;
const bool : bollean = true;
const _undefined : undefined = undefined;

const obj : object = {};
const arr  : string[] = ["1", "2", "3"];

const fn = (a : number) => {
    console.log(a);
}

const fn = (a : number, b : number) => {
    console.log(a+b);
}



// unknown
// 안정성을 조금 더 보장
// 어떤 타입이든 할당은 가능하지만 조건문으로 검사하고 사용해야한다.

const _unknown : unknown = "";
if(typeof _unknown === "string")
console.log(_unknown.length);

 

 

 

 

 

'Typescript' 카테고리의 다른 글

[TS] 전략패턴  (0) 2024.05.02
[TS] 타입 어서션 / 타입 앨리어스 / 클래스 수정자 / 제네릭  (0) 2024.04.29
[TS] interface & class  (0) 2024.04.24

+ Recent posts