01 / CREATORShared
DeliveryService
Owns dispatch(), the workflow that uses a Transport.
- Check the destination
- Call
this.createTransport() - Call
transport.deliver(shipment)
createTransport(): TransportDeclared here. Overridden by a subclass.Appearance
FACTORY METHOD / THE IDEA IN A MINUTE
A delivery company sends packages by road or sea. The dispatch process is the same; the vehicle it creates is different.
RoadDelivery creates a Truck. SeaDelivery creates a Ship. Both inherit the same process: check the destination, create transport, and ask it to deliver. Factory Method is the creation step each service can override.
THE STRUCTURE / FOUR ROLES
The creator is the delivery service. The product is the vehicle object it creates. A Truck or Ship does the delivery; the shared dispatch process coordinates the work.
Switch delivery types. The shared dispatch process and Transport interface stay the same.
01 / CREATORShared
Owns dispatch(), the workflow that uses a Transport.
this.createTransport()transport.deliver(shipment)createTransport(): TransportDeclared here. Overridden by a subclass.02 / PRODUCT INTERFACEShared
Promises the operation every vehicle must support.
deliver(shipment): DeliveryReceiptDeliveryService can use any vehicle that honors this contract.
03 / CONCRETE CREATORVaries
Inherits DeliveryService.dispatch(). Overrides createTransport() to return a Truck.
The creation choice lives here.
04 / CONCRETE PRODUCTVaries
Implements Transport. Its deliver(shipment) method drives on roads.
The vehicle-specific delivery lives here.
RoadDelivery → Truck. The pair changes; DeliveryService.dispatch() and Transport stay shared.
Now follow the creation trace below: choose a service and see how the workflow gets its vehicle.
FOLLOW THE CREATION
Step into the code. Pause at the creation hook, follow the subclass override, then bring its object back to the shared workflow.
const service = new RoadDelivery()
service.dispatch(shipment)One service instance · inherits dispatch()STEP 1 / 8
Setup creates a RoadDelivery service. It inherits dispatch() from DeliveryService. No Truck exists yet.
Inherited by RoadDelivery. Same method for every service.
dispatch(input: Shipment): DeliveryReceipt {
const shipment = validateShipment(input)
const transport = this.createTransport()
return transport.deliver(shipment)
}
Extends DeliveryService. Changes creation; inherits the rest.
class RoadDelivery extends DeliveryService {
protected createTransport(): Transport {
const transport = new Truck()
return transport
}
}
Only createTransport() is overridden.
The vehicle appears only when its constructor runs. Watch the creation step.
NOW TEST THE BENEFIT
Add a vehicle without editing the inherited dispatch() method. Then trace the new service through the same code above.
Step 1 of 8. Setup creates a RoadDelivery service. It inherits dispatch() from DeliveryService. No Truck exists yet.
A framework already owns a workflow, but applications need to supply different kinds of objects within it. Each product supports the same interface, so the workflow can use it without knowing its concrete class.
Each variation adds a subclass. For a small, stable set of delivery types, a simple conditional or factory function may be clearer. If you only need to provide an existing object, constructor injection may be enough.
Follow a delivery company from trucks only to a shared workflow for trucks, ships and planes.
Three chapters · problem, pressure, creation hookBACK FOR A REFRESHERRecall the roles, the creation hook and when the extra classes are worthwhile.
Contracts, code and tradeoffs