Lädt...


🔧 Learn Design Patterns: Understanding the Builder Pattern


Nachrichtenbereich: 🔧 Programmierung
🔗 Quelle: dev.to

When creating objects with many optional or interdependent parts, maintaining clarity and flexibility in the construction process can become a challenge. The Builder Pattern addresses this by allowing step-by-step object creation, ensuring flexibility and scalability in your code.

In this article, we’ll explore the Builder Pattern with a practical gaming scenario, explaining the problem it solves, and illustrating how it works through a real-world implementation using TypeScript.

Table of Contents

  1. Builder Pattern Definition

  2. Problems Solved with Builder Pattern

  3. Real-Life Projects That Use the Builder Pattern

Builder Pattern Definition

The Builder Pattern is a creational design pattern that decouples the construction of a complex object from its representation.

Rather than using a class constructor overloaded with numerous parameters, which can make the code difficult to read and maintain, the Builder Pattern provides a way to construct objects step by step. This approach simplifies managing optional or interdependent components, resulting in more readable and maintainable code.

Problems Solved with Builder Pattern

Imagine you are designing a game where players can create customizable characters. Each character can have the following attributes:

  • Helmet

  • Torso armor

  • Arm covers

  • Pants

  • Primary weapon

  • Secondary weapon

  • Melee weapon

Now, consider the challenges:

  1. Complex Object Construction
    Some characters require full equipment (e.g., sniper characters), while others may start with only basic armor. Managing these configurations with traditional constructors becomes overwhelming.

  2. Flexibility in Customization
    Players need to create characters step by step, with the freedom to skip or modify parts of the configuration.

  3. Readability and Maintainability
    Directly initializing these objects using constructors or long parameter lists is not only error-prone but also hard to maintain as new features are added.

Implementation

Key Components

Step 1: Character Class
Represents the complex object being built, containing attributes like armor and weapons.

interface ICharacter {
  helmet: string | null;
  torsoArmor: string | null;
  armsCover: string | null;
  pants: string | null;
  primaryWeapon: string | null;
  secondaryWeapon: string | null;
  meleeWeapon: string | null;
}

class Character implements ICharacter {
  helmet: string | null = null;
  torsoArmor: string | null = null;
  armsCover: string | null = null;
  pants: string | null = null;
  primaryWeapon: string | null = null;
  secondaryWeapon: string | null = null;
  meleeWeapon: string | null = null;

  constructor() {}
}

Step 2:ICharacterBuilder Interface
Defines the methods required to build each part of the character.

interface ICharacterBuilder {
  addHelmet(helmet: string): this;
  addTorsoArmor(armor: string): this;
  addArmsCover(armsCover: string): this;
  addPants(pants: string): this;
  addPrimaryWeapon(weapon: string): this;
  addSecondaryWeapon(weapon: string): this;
  addMeleeWeapon(weapon: string): this;
  getCharacter(): Character;
}

Step 3: CharacterBuilder Class
Implements the builder interface and provides methods for constructing each part of the character.

class CharacterBuilder implements ICharacterBuilder {
  private character: Character;

  constructor() {
    this.reset();
  }

  reset() {
    this.character = new Character();
  }

  addHelmet(helmet: string): this {
    this.character.helmet = helmet;
    return this;
  }

  addTorsoArmor(armor: string): this {
    this.character.torsoArmor = armor;
    return this;
  }

  addArmsCover(armsCover: string): this {
    this.character.armsCover = armsCover;
    return this;
  }

  addPants(pants: string): this {
    this.character.pants = pants;
    return this;
  }

  addPrimaryWeapon(weapon: string): this {
    this.character.primaryWeapon = weapon;
    return this;
  }

  addSecondaryWeapon(weapon: string): this {
    this.character.secondaryWeapon = weapon;
    return this;
  }

  addMeleeWeapon(weapon: string): this {
    this.character.meleeWeapon = weapon;
    return this;
  }

  getCharacter(): Character {
    const result = this.character;
    this.reset();
    return result;
  }
}

Step 4: Director Class
Orchestrates the building process by defining configurations for different character types.

class Director {
  private characterBuilder: CharacterBuilder;

  setCharacterBuilder(characterBuilder: CharacterBuilder) {
    this.characterBuilder = characterBuilder;
  }

  buildStarterCharacter() {
    this.characterBuilder
      .addHelmet("starter")
      .addTorsoArmor("starter")
      .addArmsCover("starter")
      .addPants("starter");
  }

  buildSniperCharacter() {
    this.characterBuilder
      .addHelmet("ghillie head cover")
      .addTorsoArmor("ghillie torso cover")
      .addArmsCover("ghillie arms cover")
      .addPants("ghillie pants")
      .addPrimaryWeapon("Bolt sniper rifle")
      .addSecondaryWeapon("pistol")
      .addMeleeWeapon("knife");
  }
}

Step 5: Client Code
Demonstrates how the Builder Pattern is used to create different character configurations.

const director = new Director();
const builder = new CharacterBuilder();
director.setCharacterBuilder(builder);
director.buildStarterCharacter();
console.log(builder.getCharacter());

director.buildSniperCharacter();
console.log(builder.getCharacter());




Problems Solved with Builder Pattern

  1. Simplifies Complex Object Creation
    By delegating the construction logic to a builder class, the client code becomes cleaner and more manageable.

  2. Improves Flexibility
    Clients can build objects step by step, adding only the parts they need.

  3. Promotes Scalability
    Adding new attributes or configurations (e.g., a wizard character) doesn’t disrupt existing code.

  4. Supports Readability
    The clear, incremental construction process is easier to understand and maintain.

Real-Life Projects That Use the Builder Pattern

  1. Game Development:
    Building customizable characters, levels, or items incrementally.

  2. UI Builders:
    Constructing dynamic user interfaces where optional components are added based on user input.

  3. Document Generators:
    Creating structured documents like PDFs or reports with optional sections.

  4. Query Builders:
    Incrementally building SQL queries or API requests.

The Builder Pattern is a versatile tool for managing complex object creation, offering flexibility and scalability while keeping your code maintainable and readable. With the provided implementation, you can now start applying this pattern to your projects!

In the next article of our Learn Design Patterns series, we’ll explore the Prototype Pattern, which is used to create new objects by cloning an existing object, known as a prototype. Stay tuned, and keep learning!

...

🔧 Learn Design Patterns: Understanding the Builder Pattern


📈 49.42 Punkte
🔧 Programmierung

🔧 Learn Design Patterns: Understanding the Adapter Pattern for Compatibility


📈 39.95 Punkte
🔧 Programmierung

🔧 Learn Design Patterns: Understanding the Abstract Factory Pattern


📈 39.95 Punkte
🔧 Programmierung

🔧 Learn Design Patterns: Understanding the Factory Method Pattern


📈 39.95 Punkte
🔧 Programmierung

🔧 Learn Design Patterns: Mastering the Singleton Design Pattern


📈 38.66 Punkte
🔧 Programmierung

🔧 Learn Design Patterns: Unlocking the Power of the Prototype Design Pattern


📈 38.66 Punkte
🔧 Programmierung

🔧 Design Pattern #7 - Builder Pattern


📈 35.21 Punkte
🔧 Programmierung

🔧 Design Patterns in Microservices. Chapter 1: Introduction to Microservices Design Patterns


📈 32.06 Punkte
🔧 Programmierung

🔧 DESIGN PATTERNS : A Deep Dive into Common Design Patterns


📈 32.06 Punkte
🔧 Programmierung

🔧 Recognizing Design Patterns in System Design - Facade pattern and AWS API Gateway


📈 31.45 Punkte
🔧 Programmierung

🔧 Understanding Builder Design Pattern


📈 31.27 Punkte
🔧 Programmierung

🔧 Understanding the Builder Design Pattern in TypeScript


📈 31.27 Punkte
🔧 Programmierung

🔧 KISS Principle: Giữ Mọi Thứ Đơn Giản Nhất Có Thể


📈 31.23 Punkte
🔧 Programmierung

🔧 Có thể bạn chưa biết (Phần 1)


📈 31.23 Punkte
🔧 Programmierung

🔧 Tìm Hiểu Về RAG: Công Nghệ Đột Phá Đang "Làm Mưa Làm Gió" Trong Thế Giới Chatbot


📈 31.23 Punkte
🔧 Programmierung

🔧 Builder Pattern-Pattern


📈 30.12 Punkte
🔧 Programmierung

🔧 Design Patterns vs. Architectural Patterns: Stop the Confusion


📈 26.97 Punkte
🔧 Programmierung

🔧 CI/CD Software Design Patterns and Anti-Patterns


📈 26.97 Punkte
🔧 Programmierung

🔧 Design Patterns in JavaScript: Creational Patterns


📈 26.97 Punkte
🔧 Programmierung

🔧 JavaScript Design Patterns: Mastering Creational, Structural, And Behavioral Patterns For Cleaner Code


📈 26.97 Punkte
🔧 Programmierung

🔧 Design Patterns #4: Unlocking Flexibility with the Bridge Pattern.


📈 26.36 Punkte
🔧 Programmierung

🔧 Design Patterns Serie — Structural Chapter: Proxy Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 🔎Exploring Design Patterns: Adapter Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 Mastering Design Patterns in JavaScript: Part 2 — The Factory Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 The Impact of Pattern Matching for Switch Expressions in Java 17 on Object-Oriented Design Patterns


📈 26.36 Punkte
🔧 Programmierung

🔧 Design Patterns - State Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 React Design Patterns: Compound Component Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 Design patterns: Part One - A brief explanation of creational pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 Why Design Patterns Matter: A Beginner's Guide to Choosing the Right Pattern


📈 26.36 Punkte
🔧 Programmierung

🔧 ⚛️ Applying Design Patterns in React: Strategy Pattern (Part 2)


📈 26.36 Punkte
🔧 Programmierung

🔧 Kotlin Design Patterns: Simplifying the Observer Pattern


📈 26.36 Punkte
🔧 Programmierung

matomo