Builder Pattern
Posted by Dustin Boston in Design Patterns.
The Builder Pattern is a creational design pattern that decouples the construction of complex objects from their representation, allowing for flexibility and reuse in object creation.
The Builder pattern decouples construction of an object from its underlying structure so that one builder can create multiple types of objects.
Source Code Listing
code.ts
class Part<T> {
constructor(
public type: string,
public value: T,
) {}
}
class Director<T> {
constructor(public builder: Builder<T>) {}
construct(structure: Array<Part<T>>) {
for (const part of structure) {
switch (part.type) {
case "a": {
this.builder.buildPartA(part);
break;
}
case "b": {
this.builder.buildPartB(part);
break;
}
default: {
this.builder.buildPartA(part);
}
}
}
}
}
class Product<U> {
constructor(public result: U[] = []) {}
append(object: U) {
this.result.push(object);
}
get() {
return this.result;
}
}
class Builder<T> {
buildPartA(_part: Part<T>) {
// Unimplemented
}
buildPartB(_part: Part<T>) {
// Unimplemented
}
}
class ConcreteBuilder1<T, U> extends Builder<T> {
product = new Product<U>();
buildPartA(part: Part<T>) {
// Example building a part
const value: U = String(part.value).toLowerCase() as unknown as U;
this.product.append(value);
}
buildPartB(part: Part<T>) {
// Example building a part
const value: U = String(part.value).toUpperCase() as unknown as U;
this.product.append(value);
}
getResult() {
return this.product;
}
}
// Other builders:
// class ConcreteBuilder2<T, U> extends Builder<T> {
// class ConcreteBuilder3<T, U> extends Builder<T> {
const client = {
run() {
const concreteBuilder = new ConcreteBuilder1<string, string>();
const director = new Director(concreteBuilder);
director.construct([new Part("a", "Hello"), new Part("b", "World")]);
const result = concreteBuilder.getResult();
console.log(result.get());
},
};
client.run();