Abstract Factory Pattern

Abstract Factory

Overview

The Abstract Factory is a creational pattern, and is used when one would like to return one of several related objects.

UML Diagram

Abstract Factory

Structural Code

namespace DesignPatterns.AbstractFactory {

  using System;

  class Program {
    static void Main() {

      Client[] clients = {
        new Client(new Factory1()),
        new Client(new Factory2())
      };

      foreach (Client client in clients) {
        client.ExamineProductA();
        client.ExamineProductB();
      }

      Console.ReadLine();
    }
  }

  interface ProductA {
    void Examine();
  }

  interface ProductB {
    void Examine();
  }

  class ProductA1 : ProductA {
    public void Examine() =>
      Console.WriteLine(nameof(ProductA1));
  }

  class ProductA2 : ProductA {
    public void Examine() =>
      Console.WriteLine(nameof(ProductA2));
  }

  class ProductB1 : ProductB {
    public void Examine() =>
      Console.WriteLine(nameof(ProductB1));
  }

  class ProductB2 : ProductB {
    public void Examine() =>
      Console.WriteLine(nameof(ProductB2));
  }

  interface Factory {
    ProductA CreateProductA();
    ProductB CreateProductB();
  }

  class Factory1 : Factory {
    public ProductA CreateProductA() => new ProductA1();
    public ProductB CreateProductB() => new ProductB1();
  }

  class Factory2 : Factory {
    public ProductA CreateProductA() => new ProductA2();
    public ProductB CreateProductB() => new ProductB2();
  }

  class Client {

    ProductA _productA;
    ProductB _productB;

    public Client(Factory factory) {
      _productA = factory.CreateProductA();
      _productB = factory.CreateProductB();
    }

    public void ExamineProductA() => _productA.Examine();
    public void ExamineProductB() => _productB.Examine();
  }

}

Structural Code Out

ProductA1
ProductB1
ProductA2
ProductB2

Structural Code Discussion

As can be seen here, we can change the factory to get a different set of related objects. If we need a new set of related objects, we can create a couple of new objects inheriting from our abstract product interfaces, and an accompanying factory inheriting from the abstract interface Factory, and our Client stays completely agnostic.

Pattern Example

namespace DesignPatterns.AbstractPattern {
  using System;
  class Program {
    static void Main() {

      Client[] customers = {
        new Client(new HondaFactory()),
        new Client(new ToyotaFactory())
      };

      foreach(Client customer in customers) {
        customer.ExamineLuxuryCar();
        customer.ExamineAffordableCar();
      } 

      Console.ReadLine();
    }
  }
  interface ICar {
    void ExamineAffordableCar();
  }
  interface ILuxuryCar {
    void ExamineLuxuryCar();
  }
  interface IFactory {
    ICar GetCar();
    ILuxuryCar GetLuxuryCar();
  }
  class HondaCar : ICar {
    public void ExamineAffordableCar() =>
      Console.WriteLine("A spacious Honda Accord.");
  }
  class HondaLuxuryCar : ILuxuryCar {
    public void ExamineLuxuryCar() =>
      Console.WriteLine("A luxurious Acura Legend.");
  }
  class HondaFactory : IFactory {
    public ICar GetCar() =>
      new HondaCar();
    public ILuxuryCar GetLuxuryCar() =>
      new HondaLuxuryCar();
  }
  class ToyotaCar : ICar {
    public void ExamineAffordableCar() =>
      Console.WriteLine("A reliable Toyota Camry.");
  }
  class ToyotaLuxuryCar : ILuxuryCar {
    public void ExamineLuxuryCar() =>
      Console.WriteLine("A bold Lexus ES Hybrid.");
  }
  class ToyotaFactory : IFactory {
    public ICar GetCar() => new ToyotaCar();
    public ILuxuryCar GetLuxuryCar() => new ToyotaLuxuryCar();
  }
  class Client {
    ICar _car;
    ILuxuryCar _luxuryCar;
    public Client(IFactory factory) {
      _car = factory.GetCar();
      _luxuryCar = factory.GetLuxuryCar();
    }
    public void ExamineAffordableCar() =>
      _car.ExamineAffordableCar();
    public void ExamineLuxuryCar() =>
      _luxuryCar.ExamineLuxuryCar();
  }
}

Example Code Out

A luxurious Acura Legend.
A spacious Honda Accord.
A bold Lexus ES Hybrid.
A reliable Toyota Camry.

Author: Peter

Thank you for visiting my profile. I encourage you to get in contact with me, and follow me on GitHub : https://github.com/emancipatedMind. I look forward to collaborating with you.

Leave a Reply

Your email address will not be published. Required fields are marked *