-
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