|
| 1 | +--- |
| 2 | +tags: |
| 3 | + - creational |
| 4 | +title: Builder Pattern |
| 5 | +created: 2026-03-31 |
| 6 | +--- |
| 7 | +## Definition |
| 8 | + |
| 9 | +The **Builder Pattern** is the Creational Pattern used to construct the objects step by step, especially when the object has many optional feature or configurable parameters. |
| 10 | + |
| 11 | +--- |
| 12 | +## Real World Analogy |
| 13 | + |
| 14 | +Imagine you are assembling a computer based on specific needs. A gaming computer, an office computer, and a basic home computer all have different requirements. A gaming computer may need a powerful GPU, high RAM, and advanced cooling, while an office computer may only need moderate RAM and no GPU. |
| 15 | + |
| 16 | +If you try to create all these computers using a single constructor with many parameters, you will end up passing unnecessary values such as null for components that are not required. |
| 17 | + |
| 18 | +``` |
| 19 | +Computer office = new Computer("ram", "rom", "cpu", "bluetooth", null); |
| 20 | +``` |
| 21 | + |
| 22 | +This approach is not clean and can lead to confusion and errors. |
| 23 | + |
| 24 | +The Builder Pattern solves this problem by allowing you to construct objects step by step and only include the required attributes. This makes the code more readable, flexible, and maintainable. |
| 25 | + |
| 26 | +--- |
| 27 | +## Why Use Builder Pattern |
| 28 | + |
| 29 | +- Avoids constructors with too many parameters |
| 30 | +- Improves readability of object creation |
| 31 | +- Allows step by step object construction |
| 32 | +- Makes code more maintainable and scalable |
| 33 | +- Helps in creating immutable objects |
| 34 | + |
| 35 | +--- |
| 36 | +### How Builder Pattern is Different from Abstract Factory Pattern? |
| 37 | + |
| 38 | +It may seem that both Builder Pattern and [[Abstract Factory Pattern]] help in object creation, but they serve different purposes. |
| 39 | + |
| 40 | +In **Builder Pattern**, we create different configurations of the same object. For example, a Computer object can have different specifications. |
| 41 | + |
| 42 | +In **Abstract Factory Pattern**, we create families of related objects by selecting from multiple implementations of a common interface. |
| 43 | + |
| 44 | +Builder focuses on how an object is constructed step by step, while Abstract Factory focuses on which object to create. |
| 45 | + |
| 46 | +--- |
| 47 | +## Design |
| 48 | + |
| 49 | +**Builder Pattern Class Diagram** |
| 50 | + |
| 51 | +```mermaid |
| 52 | +classDiagram |
| 53 | +
|
| 54 | +class Computer { |
| 55 | + -String Cpu |
| 56 | + -String Bluetooth |
| 57 | + -String GPU |
| 58 | + -int ROM |
| 59 | + -int Ram |
| 60 | + -- |
| 61 | + -Computer(Builder builder) |
| 62 | +} |
| 63 | +
|
| 64 | +class Builder { |
| 65 | + -String Cpu |
| 66 | + -String Bluetooth |
| 67 | + -String GPU |
| 68 | + -int ROM |
| 69 | + -int Ram |
| 70 | + -- |
| 71 | + +cpu(String cpu) Builder |
| 72 | + +gpu(String gpu) Builder |
| 73 | + +bluetooth(String bluetooth) Builder |
| 74 | + +Ram(int ram) Builder |
| 75 | + +Rom(int rom) Builder |
| 76 | + +build() Computer |
| 77 | +} |
| 78 | +
|
| 79 | +Computer --> Builder : uses |
| 80 | +Builder --> Computer : builds |
| 81 | +``` |
| 82 | + |
| 83 | +This diagram shows that the Builder class is responsible for constructing the Computer object step by step. The Computer class depends on the Builder to initialize its fields. |
| 84 | + |
| 85 | +--- |
| 86 | +## Implementation in Java |
| 87 | + |
| 88 | +```java title="Computer.java" |
| 89 | +class Computer { |
| 90 | + private String Cpu; |
| 91 | + private String Bluetooth; |
| 92 | + private String GPU; |
| 93 | + private int ROM; |
| 94 | + private int Ram; |
| 95 | + |
| 96 | + // Private Constructor only Builder class can call |
| 97 | + private Computer(Builder builder) { |
| 98 | + this.Cpu = builder.Cpu; |
| 99 | + this.ROM = builder.ROM; |
| 100 | + this.Bluetooth = builder.Bluetooth; |
| 101 | + this.GPU = builder.GPU; |
| 102 | + this.Ram = builder.Ram; |
| 103 | + } |
| 104 | +``` |
| 105 | + |
| 106 | +Here, the constructor of the Computer class is private. This ensures that objects cannot be created directly using new. Only the Builder class can create the object, which enforces controlled object creation. |
| 107 | + |
| 108 | +The constructor copies all values from the Builder object to the Computer object. |
| 109 | +```java title="Computer.java" |
| 110 | + // Getter Methods |
| 111 | + public String getCpu() { |
| 112 | + return Cpu; |
| 113 | + } |
| 114 | + |
| 115 | + public String getBluetooth() { |
| 116 | + return Bluetooth; |
| 117 | + } |
| 118 | + |
| 119 | + public String getGPU() { |
| 120 | + return GPU; |
| 121 | + } |
| 122 | + |
| 123 | + public int getROM() { |
| 124 | + return ROM; |
| 125 | + } |
| 126 | + |
| 127 | + public int getRam() { |
| 128 | + return Ram; |
| 129 | + } |
| 130 | +``` |
| 131 | +These are standard getter methods that allow access to the private fields of the Computer class. |
| 132 | + |
| 133 | +```java title="Computer.java" |
| 134 | + @Override |
| 135 | + public String toString() { |
| 136 | + return "Computer{" + |
| 137 | + "Cpu='" + Cpu + '\'' + |
| 138 | + ", Bluetooth='" + Bluetooth + '\'' + |
| 139 | + ", GPU='" + GPU + '\'' + |
| 140 | + ", ROM=" + ROM + |
| 141 | + ", Ram=" + Ram + |
| 142 | + '}'; |
| 143 | + } |
| 144 | +``` |
| 145 | +The `toString` method provides a readable representation of the Computer object, which is useful for debugging and printing output. |
| 146 | +```java title="Computer.java" |
| 147 | + // Static class as the Builder |
| 148 | + static class Builder { |
| 149 | + private String Cpu; |
| 150 | + private String Bluetooth; |
| 151 | + private String GPU; |
| 152 | + private int ROM; |
| 153 | + private int Ram; |
| 154 | +``` |
| 155 | +The Builder class holds the same fields as the Computer class. These fields are gradually set using builder methods. |
| 156 | +```java title="Computer.java" |
| 157 | + public Builder cpu(String cpu) { |
| 158 | + this.Cpu = cpu; |
| 159 | + return this; |
| 160 | + } |
| 161 | +``` |
| 162 | +This method sets the CPU value and returns the Builder object itself. Returning this enables method chaining. |
| 163 | + |
| 164 | +```java title="Computer.java" |
| 165 | + public Builder gpu(String gpu) { |
| 166 | + this.GPU = gpu; |
| 167 | + return this; |
| 168 | + } |
| 169 | +``` |
| 170 | +This method sets the GPU field. It is optional, so it can be skipped when not required. |
| 171 | + |
| 172 | +```java title="Computer.java" |
| 173 | + public Builder bluetooth(String bluetooth) { |
| 174 | + this.Bluetooth = bluetooth; |
| 175 | + return this; |
| 176 | + } |
| 177 | +``` |
| 178 | +This method sets the Bluetooth specification. |
| 179 | + |
| 180 | +```java title="Computer.java" |
| 181 | + public Builder Ram(int ram) { |
| 182 | + this.Ram = ram; |
| 183 | + return this; |
| 184 | + } |
| 185 | +``` |
| 186 | +This method sets the RAM value. |
| 187 | + |
| 188 | +```java title="Computer.java" |
| 189 | + public Builder Rom(int rom) { |
| 190 | + this.ROM = rom; |
| 191 | + return this; |
| 192 | + } |
| 193 | +``` |
| 194 | +This method sets the storage capacity. |
| 195 | + |
| 196 | +```java title="Computer.java" |
| 197 | + public Computer build() { |
| 198 | + return new Computer(this); |
| 199 | + } |
| 200 | + } |
| 201 | +} |
| 202 | +``` |
| 203 | +The build method creates and returns the final Computer object using the Builder instance. This is the final step of object construction. |
| 204 | + |
| 205 | +```java |
| 206 | +public static void main(String[] args) { |
| 207 | + Computer gaming = new Computer.Builder() |
| 208 | + .Ram(12) |
| 209 | + .cpu("i9") |
| 210 | + .gpu("RTX 5090") |
| 211 | + .Rom(1) |
| 212 | + .bluetooth("v7") |
| 213 | + .build(); |
| 214 | + |
| 215 | + System.out.println(gaming); |
| 216 | + |
| 217 | + Computer office = new Computer.Builder() |
| 218 | + .cpu("i5") |
| 219 | + .Ram(8) |
| 220 | + .Rom(512) |
| 221 | + .bluetooth("v5") |
| 222 | + .build(); |
| 223 | + |
| 224 | + System.out.println(office); |
| 225 | +} |
| 226 | +``` |
| 227 | +Here, two different Computer objects are created using the Builder. |
| 228 | +The gaming computer includes all specifications such as GPU and high RAM. |
| 229 | +The office computer skips the GPU since it is not required. This shows how Builder Pattern avoids unnecessary parameters and keeps object creation clean. |
| 230 | + |
| 231 | +**Output**: |
| 232 | +```bash |
| 233 | +Computer{Cpu='i9', Bluetooth='v7', GPU='RTX 5090', ROM=1, Ram=12} |
| 234 | +Computer{Cpu='i5', Bluetooth='v5', GPU='null', ROM=512, Ram=8} |
| 235 | +``` |
| 236 | + |
| 237 | +--- |
| 238 | +## Real World Example |
| 239 | + |
| 240 | +- `StringBuilder` is a common example of the Builder Pattern in Java. It allows you to construct a string step by step by appending values instead of creating multiple string objects. |
| 241 | +- `StringBuffer` works similarly to StringBuilder but is thread safe, which makes it suitable for multi threaded environments. |
| 242 | +- In `.NET` Core, the **Builder Pattern** is used for configuring applications. For example, when setting up services and middleware, the application is built step by step using a builder approach. |
| 243 | + |
| 244 | +--- |
| 245 | +## Design Principles: |
| 246 | + |
| 247 | +- **Encapsulate What Varies** - Identify the parts of the code that are going to change and encapsulate them into separate class just like the Strategy Pattern. |
| 248 | +- **Favor Composition Over Inheritance** - Instead of using inheritance on extending functionality, rather use composition by delegating behavior to other objects. |
| 249 | +- **Program to Interface not Implementations** - Write code that depends on Abstractions or Interfaces rather than Concrete Classes. |
| 250 | +- **Strive for Loosely coupled design between objects that interact** - When implementing a class, avoid tightly coupled classes. Instead, use loosely coupled objects by leveraging abstractions and interfaces. This approach ensures that the class does not heavily depend on other classes. |
| 251 | +- **Classes Should be Open for Extension But closed for Modification** - Design your classes so you can extend their behavior without altering their existing, stable code. |
| 252 | +- **Depend on Abstractions, Do not depend on concrete class** - Rely on interfaces or abstract types instead of concrete classes so you can swap implementations without altering client code. |
| 253 | +- **Talk Only To Your Friends** - An object may only call methods on itself, its direct components, parameters passed in, or objects it creates. |
| 254 | +- **Don't call us, we'll call you** - This means the framework controls the flow of execution, not the user’s code (Inversion of Control). |
| 255 | +- **A class should have only one reason to change** - This emphasizes the Single Responsibility Principle, ensuring each class focuses on just one functionality. |
0 commit comments