AbstractFactory - shoonie/StudyingDesignPattern GitHub Wiki

Intent

Provide an interface for creating families of related or dependent without specifying their concrete classes.

Diagram

disgram

Consequences

  1. It isolates concrete classes.
  2. It makes exchanging product families easy.
  3. It promotes consistency among products.
  4. Supporting new kinds of product is difficult.

Implementation

  1. Factory as singletons.
  2. Creating the products.
  3. Defining extensible factories.

Sample Code

#include <iostream>
using namespace std;
enum {human,troll};

class Unit //abstract product
{  
public:
    virtual void SaySomething() = 0;
};

class DeathKnight_Human : public Unit //concrete product
{
public:
    void SaySomething() { cout << "I am a DK of human\n"; }
};

class Hunter_Human : public Unit //concrete product
{
public:
    void SaySomething() { cout << "I am a Hunter of human\n"; }
};

class DeathKnight_Troll : public Unit //concrete product
{
public:
    void SaySomething() { cout << "I am a DK of TROLL\n"; }
};

class Hunter_Troll : public Unit //concrete product
{
public:
    void SaySomething() { cout << "I am a Hunter of Troll\n"; }
};

class Factory  // Abstract factory has interface.
{
public:
    virtual Unit *create_DK() = 0;
    virtual Unit *create_Hunter() = 0;
};

class HumanFactory : public Factory //concreate factory
{ 
public:
    Unit * create_DK() {
        return new DeathKnight_Human;
    }
    Unit *create_Hunter() {
        return new Hunter_Human;
    }
};

class TrollFactory : public Factory //concreate factory
{
public:
    Unit * create_DK() {
        return new DeathKnight_Troll;
    }
    Unit *create_Hunter() {
        return new Hunter_Troll;
    }
};

class Client //client should use only interfaces declared 
            //by AbstractFactory and AbdtractProduct.
{
private:
    Factory * factory;
public:
    Client(Factory *f) 
    {
        factory = f;
    }
    void buildDK_and_saysomthing()
    {
        Unit *unit = factory->create_DK();
        unit->SaySomething();
    }
    void buildHunter_and_saysomthing() 
    {
        Unit *unit = factory->create_Hunter();
        unit->SaySomething();
    }
};

int main() 
{
    int current_type = human;
    Factory *factory;
    if(current_type == human)
        factory = new HumanFactory;
    else
        factory = new TrollFactory;

    Client *factoryClient = new Client(factory);
    factoryClient->buildDK_and_saysomthing();
    factoryClient->buildHunter_and_saysomthing();
}
⚠️ **GitHub.com Fallback** ⚠️