Abstract Factory Design Pattern - DeanHristov/ts-design-patterns-cheat-sheet GitHub Wiki

An Abstract Factory is a creational design pattern that lets you produce families of related objects without specifying their concrete classes. This pattern extends a Factory Method pattern. A simple UML diagram can be seen here.

A Great fit when:

  • It is good to use when the code needs to work with various families of related products, but we don’t want it to depend on the concrete classes of those products—they might be unknown beforehand or you simply want to allow for future extensibility.

Example:

The contracts

// Product type 1
export interface IButton {
  name: string;

  click(): void;
}

// Product type 2
export interface IWindow {
  title: string;

  open(): void;

  close(): string;

  minimize(): string;
}

// The factory creator
export interface IFactoryCreator {
  createButton(): IButton;

  createWindow(): IWindow;
}

A product 1

class MacButton implements IButton {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  click(): void {
    // TODO Do some code..
  }
}

A product 2

class WinButton implements IButton {
  name: string;

  constructor(name: string) {
    this.name = name;
  }

  click(): void {
    // TODO Do some code..
  }
}

A product 3

class MacWindow implements IWindow {
  title: string;

  constructor(title: string) {
    this.title = title;
  }

  close(): void {}

  minimize(): void {}

  open(): void {}
}

A product 4

class WinWindow implements IWindow {
  title: string;

  constructor(title: string) {
    this.title = title;
  }

  close(): void {}

  minimize(): void {}

  open(): void {}
}

A factory 1

class MacPC implements IFactoryCreator {
  createButton(): IButton {
    return new MacButton('Click me');
  }

  createWindow(): IWindow {
    return new MacWindow('Finder');
  }
}

A factory 2

class WindowsPC implements IFactoryCreator {
  createButton(): IButton {
    return new WinButton('Click me');
  }

  createWindow(): IWindow {
    return new WinWindow('File Explorer');
  }
}

The Client (Application)

class ApplicationGUI {
  factory: IFactoryCreator;

  constructor(factory: IFactoryCreator) {
    this.factory = factory;
  }

  openWindow(): void {
    const win: IWindow = this.factory.createWindow();

    win.open();
  }

  clickOnButton(): void {
    const btn: IButton = this.factory.createButton();

    btn.click();
  }
}
Code in action
const windowsGUI: ApplicationGUI = new ApplicationGUI(new WindowsPC());
const macGUI: ApplicationGUI = new ApplicationGUI(new MacPC());

windowsGUI.openWindow();
macGUI.clickOnButton();

More info can be found on the wiki page.