[TS] Builder 패턴

단비·2023년 3월 13일
0

인강

목록 보기
10/15
  • builder 패턴
    • 생성자 축약형을 사용할 경우 선택하지 않은 값도 출력됨

      export class UserEntity{
          name?: string;
          age?: number;
          marketing?: boolean;
      
          constructor(name?: string, age?: number, marketing?: boolean){
              if(name) this.name = name;
              if(age) this.age = age;
              if(marketing != undefined) this.marketing = marketing;
          }
      
          // 아래 방법을 사용할 경우 없는 값도 전부 출력 됨(선택한 값만 출력되는게 아니라 전부 출력됨[undefined도 출력됨])
          // constructor(public name: string, public age: number, public marketing: boolean){}
      
          static Builder = class { // Builder 변수에 익명클래스 생성
              private _name?: string;
              private _age?: number;
              private _marketing?: boolean;
      
              // 원래 class 의 필드와 이름이 같음 함수 = 메소드
              name(newName: string){
                  this._name = newName
                  return this;
              }
      
              age(newAge: number){
                  this._age = newAge > 0 ? newAge : 0;
                  return this;
              }
      
              marketing(newMarketing: boolean){
                  this._marketing = newMarketing
                  return this;
              }
      
              build(): UserEntity {
                  return new UserEntity(this._name, this._age, this._marketing)
              }
          }
      }
    • 스프링의 repository처럼 사용

      import { UserEntity } from "./builder";
      
      const newUser: UserEntity = new UserEntity.Builder()
          .name("danbi")
          .age(25)
          .marketing(false)
          .build();
      
      console.log(newUser)

  • 데코레이터를 이용한 빌더 패턴
    • 빌더 모듈 생성

      export function Builder<T extends { new (...args: any[]): {} }> (
          constructor: T
      ) {
          const keys = Object.keys(new constructor())
      
          return class extends constructor{
              static Builder = class {
                  constructor(){
                      for(let key of keys){
                          Object.defineProperties(this, {
                              ["_" + key]: {
                                  value: this[key],
                                  enumerable: true,
                                  writable: true
                              },
                              [key]: {
                                  value: (newValue: any) => {
                                      this["_" + key] = newValue
                                      return this
                                  },
                                  enumerable: true
                              }
                          })
                      }
                  }
      
                  build(){
                      return new constructor(
      										// 오브젝트 키들 중 _로 시작하는 값을 필터링해 반복문으로 뽑기
                          ...Object.keys(this).filter((e) => (e.startsWith("_") ? true : false)).map(e => this[e])
                      )
                  }
              }
          }
      }
    • 빌더데코레이터 선언

      import { Builder } from "./deco";
      class BuilderInit{
          static Builder = class {
              build(){}
              [props: string]: Function;
          }
      }
      
      @Builder
      export class PostEntity extends BuilderInit{
          constructor(public title: string, public content: string, public author: string) {
              super()
          }
      }
profile
tistory로 이전! https://sweet-rain-kim.tistory.com/

0개의 댓글