Lab
Facade
type AlterationRequest = { customer: string; garment: string; work: string };
type WorkOrder = { id: string; request: AlterationRequest };
type IntakeResult = { orderId: string; slipPrinted: boolean };
// The subsystem: four services, each with one job.
class Validator {
check(request: AlterationRequest): void {
const { customer, garment, work } = request;
if (!customer || !garment || !work) throw new Error('incomplete request');
}
}
class Queue {
private next = 1;
reserve(): string {
return `ALT-${this.next++}`;
}
}
class OrderBook {
orders: WorkOrder[] = [];
record(order: WorkOrder): void {
this.orders.push(order);
}
}
class Printer {
jammed = true; // the first slip jams; the next ones print
print(order: WorkOrder): void {
if (this.jammed) {
this.jammed = false;
throw new Error(`printer jammed on ${order.request.customer}'s slip`);
}
}
}
// The facade: one operation for the whole intake.
class IntakeDesk {
constructor(
private validator: Validator,
private queue: Queue,
private book: OrderBook,
private printer: Printer,
) {}
acceptAlteration(request: AlterationRequest): IntakeResult {
this.validator.check(request);
const order = { id: this.queue.reserve(), request };
this.book.record(order);
try {
this.printer.print(order);
return { orderId: order.id, slipPrinted: true };
} catch {
return { orderId: order.id, slipPrinted: false };
}
}
}
const book = new OrderBook();
const desk = new IntakeDesk(new Validator(), new Queue(), book, new Printer());
// Each caller makes one call and tells its customer what happened.
function take(caller: string, request: AlterationRequest): void {
try {
const result = desk.acceptAlteration(request);
const slip = result.slipPrinted ? 'slip printed' : 'no slip';
console.log(`${caller}: accepted ${result.orderId}, ${slip}`);
} catch (error) {
console.log(`${caller}: not accepted (${(error as Error).message})`);
}
}
take('counter', { customer: 'Mina', garment: 'blue coat', work: 'reline' });
take('phone', { customer: 'Omar', garment: 'grey suit', work: '' });
take('partner', { customer: 'Lena', garment: 'linen dress', work: 'hem' });
const recorded = book.orders.length;
console.log(`work orders recorded: ${recorded}`);
TODO
Visual to come