ABOUT ME

jacey.park.dev@gmail.com \n 5년차 프론트엔드 개발자

Today
-
Yesterday
-
Total
-
  • Typescript에서 Builder Pattern 사용하기
    Dev 2021. 5. 10. 01:25

    들어가며

    개발을 하면서 빌더 패턴에 대해서 정확히 알지 못한 상태로 나도 모르게 필더패턴 비스무리하게 사용중이었는데, 자바스크립트 디자인 패턴 책을 읽으면서 자세히 알게 되어 관심을 가지고 찾아보게 되었습니다.

     

    Builder Pattern이란?

    - 클래스의 구축을 단순화 하고 사용자가 전문지식 없이 클래스를 구축할 때 사용하는 패턴.

    - 생성 패턴(인스턴스를 만드는 절차를 추상화 하는 패턴)의 일종이다.

     

    언제 쓰는가?

    예를들어, 함수가 여러개의 인자를 받고 있고, 중간 중간에 null값을 넘겨줘야하는 인자가 있을 경우

    complicatedMethod('HELLO', true, 3.141592, null, null, 'BYE');

    다음과 같이 쓰는 경우가 있을 수 있습니다.

     

    해당 코드를 살펴보면

    1. 함수 사용자가 인자의 자리를 고려하며 직접 입력할 인자가 너무 많다.

    2. 인자가 너무 많아서 무엇을 하는 함수인지 일단 잘 모르겠고 무섭다. (개인적인 의견)

    3. 거기다가 null 과 같은 값까지 중간중간 직접 넘기면.. 😭 코드를 처음보는 사람은 당황할 수가 있다.

     

    이러한 문제점을 builder 패턴을 통해서 조금은 극복 할 수 있습니다.

     

    그래서 빌더패턴을 통해 APIBuilder라는 것을 구현 해 볼건데, 이 APIBuilder는 아래 인자들을 통해 API Request를 위한 인자들을 꾸려 나갑니다.

     

    1. url (Request URL): string, required

    2. method (Request Method): string required

    3. body (Request Body): any optional

    4. ResponseDataDepth (response의 data중 진짜 data의 위치. API마다 내가 필요한 진짜 데이터가 있는 위치가 다를 수 있으니..): string optional

     

    코드

     

    그러면 코드를 볼 차례인데, 먼저 구현한 코드를 보기 전에 결론이 궁금하니 호출은 어떻게 하는지 먼저 보고 가겠습니다.

    const productListAPI = new APIBuilder("/product-list", "GET")// required
      .setBody({ cutePower: 100 }) // Request Body 설정
      .build(); // 빌드! (위에서 설정한 파라미터를 통해 API 객체 생성 후 Return)
    
    productListAPI.fetch(); // 생성된 객체를 바탕으로 API Fetch
    

     

    일단 코드를 보면 뭔진 모르겠지만 APIBuilder를 호출하면서 필수 인자들을 넘겨주었습니다.

    그리고 나서는 setBody()라는 메소드를 통해서 body를 설정해주었습니다.

    그리고 위에서 설정한 인자들을 바탕으로 API 객체를 생성한 후 Return 하였고, 생성된 객체에서 fetch()를 통해 API Request를 날립니다.

     

    그러면 이제 진짜 구현한 코드를 살펴보겠습니다. (참고로 Typescript 입니다.)

     

    먼저, API 클래스입니다.

    class API {
      private url: string;  // request URL
      private method: string; // request Method
    
      private body: any; // request Body
      private responseDataDepth: string; // Response body 객체 중 실제 데이터의 위치(?)
    
      constructor(builder: APIBuilder) {
        this.url = builder.url;
        this.method = builder.method;
        this.body = builder.body; 
        this.responseDataDepth = builder.responseDataDepth;
      }
      
      fetch() {
        // 여기서 이제 필드들을 가지고 실제 request를 하면 된다!
        console.log(this.url);
        console.log(this.method);
        console.log(this.body);
        console.log(this.responseDataDepth);
    
        return `${this.url}, ${this.method}, ${this.body}, ${this.responseDataDepth}`
      }
    }
    

     

    단순한 클래스이며, 생성자를 통해 인자를 받으며, fetch()라는 메소드에서는 실제 API Request를 하게 됩니다.

     

    다음은 API Builder입니다.

    class APIBuilder {
      public url: string;
      public method: string;
    
      public body: any;
      public responseDataDepth: string;
    
      constructor(reqURL: string, reqMethod: string) {
        this.url = reqURL;
        this.method = reqMethod;
      }
    
      public setBody(body) {
        this.body = body;
        return this;
      }
    
      public setResponseDataDepth(depth) {
        this.responseDataDepth = depth;
        return this;
      }
    
      public build() {
        return new API(this);
      }
    }

    필수 인자들에 대해서는 생성자를 통해 받을 수 있고,

    setBody()와 setResponseDataDepth()라는 메소드를 통해 optional인 인자들을 설정할 수 가 있으며, 

    마지막으로 build()를 통해 API 객체를 생성할 수 있습니다.

    const productListAPI = new APIBuilder("/product-list", "GET")// required
      .setBody({ cutePower: 100 }) // Request Body 설정
      .build(); // 빌드! (위에서 설정한 파라미터를 통해 API 객체 생성 후 Return)
    
    productListAPI.fetch(); // 생성된 객체를 바탕으로 API Fetch.
    

     

    다시 돌아와서 생성하고 호출하는 코드를 보면 setResponseDataDepth() 라는 메소드를 호출하지 않은 것을 볼 수 있는데, 이는 responseDataDepth가 optional이기 때문에 호출하지 않음으로써 optional한 값을 설정할 수 있는 것입니다.

     

     

     

     

    참고한 글

    [생성패턴] 빌더패턴(Builder pattern) 이해 및 예제 readystory.tistory.com/121

     

    'Dev' 카테고리의 다른 글

    Next.js 13 번역  (0) 2022.12.16
    Factory Method Pattern  (0) 2021.05.11
    [DEV]SPA 알아보기 - Single Page Application  (0) 2018.05.18
    [방법론] TDD란?  (0) 2018.04.20
    [JS] Webpack 4 setting 'mode' option  (0) 2018.03.15

    댓글

Designed by Tistory.