We wish to create order instances for SKU sku123
and with price $10
. The only thing that will vary for each order is the quantity
.
The Order class has these properties.
export class Order {
public readonly sku;
public readonly quantity;
public readonly price;
public readonly total;
}
}
The orders will be built like this:
let builder = new OrderBuilder();
const order1 = builder.setQuantity(10).setSKU('sku123').setPrice(10).build();
const order2 = builder.setQuantity(20).setSKU('sku321').setPrice(100).build();
console.log(order1);
console.log(order2);
Approach
The full implementation for our immutable Typescript class and the corresponding builder look like this:
export class Order {
public readonly sku;
public readonly quantity;
public readonly price;
public readonly total;
constructor(builder:OrderBuilder) {
this.sku = builder.sku;
this.quantity = builder.quantity;
this.price = builder.price;
this.total = builder.total;
}
}
export class OrderBuilder {
public readonly price:number;
public readonly sku:string;
public quantity:number;
public total:number;
constructor(sku:string, price:number){
this.price = price;
this.sku = sku;
}
setQuantity(quantity: number) {
this.quantity = quantity;
return this;
}
private computeTotal() {
this.total = this.quantity*this.price;
}
build() {
this.computeTotal();
return new Order(this);
}
}
With that implementation we can build two orders with quantities 10
and 20
like this:
let builder = new OrderBuilder('sku123', 10);
const order1 = builder.setQuantity(10).build();
const order2 = builder.setQuantity(20).build();
console.log(order1);
console.log(order2);
Flexibility
Since our builders sku
and price
properties are readonly
we are passing these in via the builders constructor. This means we can not change these properties post builder construction, thus the design is a bit rigid.
If we want to change these properties on the fly we can remove the readonly markers and implement builder setters for sku and price . We can now change these properties on the fly as well, giving us more flexibility. Here is a demo: