namespace WhoNeedsAFactory {
class ToyCar {
whatIsIt(): void {
console.log("this is a toy car");
}
play(): void {
console.log("vroom!!");
}
}
class ToyProductionPlant {
makePresents(): ToyCar[] {
let carA = new ToyCar();
let carB = new ToyCar();
let carC = new ToyCar();
return new Array(carA, carB, carC);
}
makeAToy(): ToyCar {
return new ToyCar();
}
}
let tpp = new ToyProductionPlant();
let car = tpp.makePresents();
car.forEach((x) => x.play());
}
//output:
vroom!!
vroom!!
vroom!!
The code above demonstrates how a simple toy factory can make the only toy they know about -- a car. But what if they learned to create other toys?
First, let's extract something in common from all elements so that we can operate on an abstraction and not a concrete entity
interface Present {
whatIsIt(): string;
play(): string;
}
Then let's define concrete classes and ensure they implement the common interface:
class ToyCar implements Present {
whatIsIt(): string {
return "This is a toy car";
}
play(): string {
return "vroom!!";
}
}
class ToyBoat implements Present {
play(): string {
return "Off we go!";
}
whatIsIt(): string {
return "This is a toy boat";
}
}
class BagOfCoal implements Present {
play(): string {
return "You now have a dirty face!";
}
whatIsIt(): string {
return "Bag of coal";
}
}
Next, the Creator class, this is where the magic of extensibility happens:
enum ToyType {
car,
boat,
coal,
}
//Creator class
class ToyFactory {
makeAToy(typeOfToy: ToyType): Present {
switch (typeOfToy) {
case ToyType.boat: {
return new ToyBoat();
}
case ToyType.car: {
return new ToyCar();
}
case ToyType.coal: {
return new BagOfCoal();
}
}
}
}
Finally, the wire-up:
class ElvesFactory {
toyFactory: ToyFactory;
constructor(toyFactory: ToyFactory) {
this.toyFactory = toyFactory;
}
makeToys(order: ToyType[]) {
order.forEach((x) => {
let toy = this.toyFactory.makeAToy(x);
console.log(toy.whatIsIt());
console.log(toy.play());
});
}
}
Test:
//check:
let tf = new ToyFactory();
let toyProductionFacility = new ElvesFactory(tf);
let order = new Array(
ToyType.boat,
ToyType.car,
ToyType.boat,
ToyType.car,
ToyType.coal,
ToyType.car
);
toyProductionFacility.makeToys(order);
//output:
This is a toy boat
Off we go!
This is a toy car
vroom!!
This is a toy boat
Off we go!
This is a toy car
vroom!!
Bag of coal
You now have a dirty face!
This is a toy car
vroom!!
If elves learn to make more toys, there will need to be a class created for that toy that implements the Present interface, add a value to the enum,
and then a condition to create that type of toy into the creator class.