Lukas Gamper, uSystems GmbH
The factory pattern is one of the creational software design patterns.
This design pattern provides a generic interface to create objects.
It works with a creator that produces products. When using the factory pattern, we are not required to use the new keyword because the instantiation of additional classes are done in the factory implementation.
// beerfactory.ts
export class BeerFactory {
constructor(
public brand: string,
public name: string
) {}
public get label(): void {
console.log(`${this.name} by ${this.brand}`);
}
}
export default function createBeer(brand: string, name: string) {
return new BeerFactory(name, health);
}
// app.ts
import createBeer, { BeerFactory } from './beerfactory';
const waldbier: BeerFactory = createBeer('Waldbeer', 'Pilgrim');
waldbier.label(); // Waldbeer by Pilgrim
// beerfactory.ts
import Beer from 'beer';
export default class BeerFactory {
private instances: Beer[] = [];
public create(brand: string, name: string) {
const instance: Beer = new Beer(brand, name);
this.instances.push(instance);
return instance;
}
public get beers(): Beer[] {
return [...this.instances];
}
}
// beer.ts
export default class Beer {
constructor(
public brand: string,
public name: string
) {}
public get label(): void {
console.log(`${this.name} by ${this.brand}`);
}
}
// beerfactory.ts
import Beer from 'beer';
export default class BeerFactory {
private instances: Beer[] = [];
public create(brand: string, name: string) { ... }
public get beers(): Beer[] {
return [...this.instances];
}
}
// beer.ts
export default class Beer {
...
public get label(): string {
console.log(`${this.name} by ${this.brand}`);
}
}
// app.ts
import Beer from './beer';
import BeerFactory from './beerfactory';
const factory: BeerFactory = new BeerFactory();
const waldbier = createBeer('Waldbeer', 'Pilgrim');
waldbier.label(); // Waldbeer by Pilgrim
factory.beers.forEach(beer => beer.label) // Waldbeer by Pilgrim
// strongbeer.ts
import IBeer from 'ibeer'
export default class StrongBeer extends IBeer {
constructor(
public brand: string,
public name: string
) {}
public get label(): string {
console.log(`A strong ${this.name} by ${this.brand}`);
}
}
// ibeer.ts
export default interface IBeer {
brand: string;
name: string;
readonly label: string;
}
// lightbeer.ts
import IBeer from 'ibeer'
export default class LightBeer extends IBeer {
constructor(
public brand: string,
public name: string
) {}
public get label(): string {
console.log(`A light ${this.name} by ${this.brand}`);
}
}
// beerfactory.ts
import IBeer from 'ibeer';
import LightBeer from 'lightbeer';
import StrongBeer from 'strongbeer';
export class BeerFactory {
private instances: IBeer[] = [];
public createStrong(brand: string, name: string) {
const instance: StrongBeer = new StrongBeer(brand, name);
this.instances.push(instance);
return instance;
}
public createLight(brand: string, name: string) {
const instance: LightBeer = new LightBeer(brand, name);
this.instances.push(instance);
return instance;
}
public get beers(): IBeer[] {
return [...this.instances];
}
}
// ibeer.ts
export default interface IBeer {
brand: string;
public name;
readonly label: string;
}