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

JOI - API schema validation
admin12/06/2023

JOI - API schema validation
Data validation is one of topics that I am interesting. I always review my code after developed features or fixed bugs. There are many places where need to validate data, it is really terrible. Some cases, we need to validate data input because ensure the data into API, it will not make any problems to crash system.
TypeScript Design Pattern - Builder
admin07/08/2023

TypeScript Design Pattern - Builder
TypeScript Design Pattern - Builder
Difference Between Stack and Queue
admin07/04/2024

Difference Between Stack and Queue
In the fundamental data structure, besides the linked list, the stack and queue are also used widely in computer science and programming.
Mới nhất

Data structure: Singly Linked List
admin07/04/2024

Data structure: Singly Linked List
In this article, I will show you how to set up a singly linked list algorithm in Python.
TypeScript Design Pattern - Singleton
admin07/08/2023

TypeScript Design Pattern - Singleton
The singleton ensures only a single install is created in a class and provides a method to access this instance everywhere in a codebase.
TypeScript Design Pattern - Abstract Factory
admin07/08/2023

TypeScript Design Pattern - Abstract Factory
The abstract factory pattern is one of five design patterns in the Creational Design Pattern group. The abstract factory provides an interface for creating families of related or dependent objects without specifying their concrete classes.
Đ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