/*Abstract factory pattern*/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace DesignPatterns.AbstractFactory
{
public class GenericFactory
where T : new()
{
public T CreateObject()
{
return new T();
}
}
public abstract class CarFactory
{
public abstract SportsCar CreateSportsCar();
public abstract FamilyCar CreateFamilyCar();
}
public abstract class FamilyCar
{
public abstract void Speed(SportsCar abstractFamilyCar);
}
public abstract class SportsCar
{
}
public class MercedesFactory : CarFactory
{
public override SportsCar CreateSportsCar()
{
return new MercedesSportsCar();
}
public override FamilyCar CreateFamilyCar()
{
return new MercedesFamilyCar();
}
}
class MercedesSportsCar : SportsCar
{
}
class MercedesFamilyCar : FamilyCar
{
public override void Speed(SportsCar abstractSportsCar)
{
Console.WriteLine(GetType().Name + " is slower than "
+ abstractSportsCar.GetType().Name);
}
}
public class Driver
{
private CarFactory _carFactory;
private SportsCar _sportsCar;
private FamilyCar _familyCar;
public Driver(CarFactory carFactory)
{
CarFactory = carFactory;
SportsCar = CarFactory.CreateSportsCar();
FamilyCar = CarFactory.CreateFamilyCar();
}
private CarFactory CarFactory
{
get { return _carFactory; }
set { _carFactory = value; }
}
private SportsCar SportsCar
{
get { return _sportsCar; }
set { _sportsCar = value; }
}
private FamilyCar FamilyCar
{
get { return _familyCar; }
set { _familyCar = value; }
}
public void CompareSpeed()
{
FamilyCar.Speed(SportsCar);
}
}
}
The factory method is also implemented using common interface each of which returns objects.
// Abstract factory using common interface
public interface IFactory1
{
IPeople GetPeople();
}
public class Factory1 : IFactory1
{
public IPeople GetPeople()
{
return new Villagers();
}
}
public interface IFactory2
{
IProduct GetProduct();
}
public class Factory2 : IFactory2
{
public IProduct GetProduct()
{
return new IPhone();
}
}
public abstract class AbstractFactory12
{
public abstract IFactory1 GetFactory1();
public abstract IFactory2 GetFactory2();
}
public class ConcreteFactory : AbstractFactory12
{
public override IFactory1 GetFactory1()
{
return new Factory1();
}
public override IFactory2 GetFactory2()
{
return new Factory2();
}
}
The following is the real word example to abstract factory pattern, which makes it much easier to understand.
// Abstract Factory pattern -- Real World example
namespace Abstract.RealWorldExample
{
///
/// MainApp startup class for Real-World
/// Abstract Factory Design Pattern.
///
class MainApp
{
///
/// Entry point into console application.
///
public static void Main()
{
// Create and run the African animal world
ContinentFactory africa = new AfricaFactory();
AnimalWorld world = new AnimalWorld(africa);
world.RunFoodChain();
// Create and run the American animal world
ContinentFactory america = new AmericaFactory();
world = new AnimalWorld(america);
world.RunFoodChain();
// Wait for user input
Console.ReadKey();
}
}
///
/// The 'AbstractFactory' abstract class
///
abstract class ContinentFactory
{
public abstract Herbivore CreateHerbivore();
public abstract Carnivore CreateCarnivore();
}
///
/// The 'ConcreteFactory1' class
///
class AfricaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Wildebeest();
}
public override Carnivore CreateCarnivore()
{
return new Lion();
}
}
///
/// The 'ConcreteFactory2' class
///
class AmericaFactory : ContinentFactory
{
public override Herbivore CreateHerbivore()
{
return new Bison();
}
public override Carnivore CreateCarnivore()
{
return new Wolf();
}
}
///
/// The 'AbstractProductA' abstract class
///
abstract class Herbivore
{
}
///
/// The 'AbstractProductB' abstract class
///
abstract class Carnivore
{
public abstract void Eat(Herbivore h);
}
///
/// The 'ProductA1' class
///
class Wildebeest : Herbivore
{
}
///
/// The 'ProductB1' class
///
class Lion : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Wildebeest
Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);
}
}
///
/// The 'ProductA2' class
///
class Bison : Herbivore
{
}
///
/// The 'ProductB2' class
///
class Wolf : Carnivore
{
public override void Eat(Herbivore h)
{
// Eat Bison
Console.WriteLine(this.GetType().Name + " eats " + h.GetType().Name);
}
}
///
/// The 'Client' class
///
class AnimalWorld
{
private Herbivore _herbivore;
private Carnivore _carnivore;
// Constructor
public AnimalWorld(ContinentFactory factory)
{
_carnivore = factory.CreateCarnivore();
_herbivore = factory.CreateHerbivore();
}
public void RunFoodChain()
{
_carnivore.Eat(_herbivore);
}
}
}