Danh mụcThẻBài viết

admin

I'm a Full-stack developer

Thẻ

Linked List
Data Structure
Chat GPT
Design Pattern
Microservices
API
AWS CDK
ReactJS
AWS Lightsail
Flutter Mobile
TypeScript Design Pattern - Builder
Ngày đăng: 07/08/2023

What is a builder pattern?

The builder pattern is one of the Creational pattern groups. The responsibility is to build a complex object with basic objects step by step.


When should I use the builder pattern?

The builder pattern should be used when a developer wants to:


  • Having a lot of constructors.
  • Control the build process.
  • Decouple the build complex object process from the component of an object.
  • Initialize an object that has greater than 4 properties including required and optional properties.


How to implement

For example, we will create an object to validate API schema including body, param, and query.


base.validation.ts
export class BaseValidation {
  protected readonly _httpRequest: { params?: any; query?: any; body?: any };

  constructor() {
    this._httpRequest = {};
  }

  findOneBuilder() {
    return this;
  }

  deleteOneBuilder() {
    this._httpRequest.params = Joi.object().keys({
      id: Joi.string().custom(objectId),
    });


    return this;
  }

  updateOneBuilder() {
    this._httpRequest.params = Joi.object().keys({
      id: Joi.string().custom(objectId),
    });


    return this;
  }

  insertOneBuilder() {
    return this;
  }

  searchBuilder() {
    this._httpRequest.query = {};


    return this;
  }

  withBody(body) {
    this._httpRequest.body = body;


    return this;
  }

  withFilter(filter) {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      ...filter,
      isAll: Joi.string(),
      includeId: Joi.string(),
    };

    return this;
  }

  withPopulate() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      populate: Joi.string(),
    };

    return this;
  }

  withSelect(select) {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      select: select,
    };

    return this;
  }

  withSortBy() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      sort_fields: Joi.string(),
      sort: Joi.string(),
    };

    return this;
  }

  withLimit() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      limit: Joi.number().integer(),
    };

    return this;
  }

  withPage() {
    this._httpRequest.query = {
      ...this._httpRequest.query,
      page: Joi.number().integer(),
    };

    return this;
  }

  build() {
    return {
      ...(this._httpRequest.body && { body: this._httpRequest.body }),
      ...(this._httpRequest.query && { query: this._httpRequest.query }),
      ...(this._httpRequest.params && { query: this._httpRequest.params }),
    };
  }
}


tag.validation.ts
export class TagValidation extends BaseValidation {
  constructor() {
    super();
  }

  searchBuilder() {
    return super
      .searchBuilder()
      .withSelect(Joi.custom(this.select))
      .withPage()
      .withPopulate()
      .withLimit()
      .withSortBy()
      .withFilter({
        name: Joi.string(),
      })
      .build();
  }

  private select(value: string, helpers: CustomHelpers) {
    const selectFields = ['name', 'description', 'slug'];

    if (value) {
      const valueList = value.split(',');
      const difference = valueList.filter((x) => !selectFields.includes(x));

      if (difference.length > 0) {
        return helpers.message({ custom: `"{{#label}}" must be in ${selectFields}` });
      }
    }

    return value;
  }
}


tag.route.ts
validateSchemaMiddleware(new TagValidation().searchBuilder());


Execution result

/tags?limit=1&select=name
{
    "statusCode": "10000",
    "status": 200,
    "message": "",
    "data": {
        "record": [
            {
                "id": 6,
                "name": "React JS"
            }
        ],
        "limit": 1,
        "total": 6,
        "page": 1
    }
}


/tags?limit=1&select=title
{
    "statusCode": "10001",
    "status": 400,
    "message": "Invalid request",
    "data": {
        "query": [
            "\"\"select\"\" must be in name,description,slug"
        ]
    }
}


Pros and Cons

Pros:


  • Support, and eliminate the need to write many constructors.
  • The code is easier to read and easier to maintain when the number of properties is required to create an object from 4 or 5 properties.
  • Reduce the number of constructors, no need to pass null values for unused parameters.
  • Safer Constructed Objects.
  • Gives you better control over the build process.
  • It is possible to create immutable objects.

Cons:


  • Duplicate code.
  • Rase code complexity.


Wrapping Up

Thank you for reading, and happy coding!

I hope this article will help make the concepts of the Builder Pattern

Đề xuất

Semantic Versioning NodeJS
admin07/07/2023

Semantic Versioning NodeJS
How to Use Semantic Versioning in NPM
Part 1: Build a Chat App with ReactJS + Material UI
admin13/09/2023

Part 1: Build a Chat App with ReactJS + Material UI
In this article, I would like to introduce using ReactJS and material UI to build a Chat App.
Mới nhất

Part 4: Creating Static Home Page on Ghost CMS
admin17/06/2023

Part 4: Creating Static Home Page on Ghost CMS
I believe that many of you are asking the question: How to fix the home page of Ghost CMS as desired? and are struggling to find many different sources of documentation.
Flutter push notification
admin14/06/2023

Flutter push notification
Welcome everyone, in this article, we will implement flutter push notification through APNs (Apple Push Notification Service) and FCM (Firebase Cloud Message), and manage messages sent using AWS SNS (Amazon Simple Notification Service).
Create Project with Express + TypeScript + ESLint + Auto Reload
admin12/06/2023

Create Project with Express + TypeScript + ESLint + Auto Reload
In this article, I introduce to you how to initialize an Express + TypeScript project.
Đinh Thành Công Blog

My website, where I write blogs on a variety of topics and where I have some experiments with new technologies.

hotlinelinkedinskypezalofacebook
DMCA.com Protection Status
Góp ý
Họ & Tên
Số điện thoại
Email
Nội dung
Tải ứng dụng
hotline

copyright © 2023 - AGAPIFA

Privacy
Term
About