c++设计模式:抽象工厂模式(Abstract Factory Pattern)

定义:

抽象工厂模式提供一个接口,用于创建相关或依赖对象的家族,而不需要明确指定具体类。

场景:

我们的披萨商店正在加速的扩建,已经接了好多城市的加盟邀请。可是各地口味不同,如果每个地市都定义不同的披萨类型,那么后期的维护将是十分头痛的,根据分析,我们披萨的种类是固定的,变动的其实就是披萨中添加的原料类型和原料的分量,因为不同的地方所生产的原料也是不同的。所以根据总部意见,打算在各地建立一个原料工厂,制作的披萨还是那些披萨,只是各地通过自己的工厂生产披萨的原料,加入到自己的披萨当中,这样,虽然生产的流程不变,但是最终的披萨口味确实符合了当地人民的需求。我们的披萨商店现在可以放心的到处开分店啦。

类图:

c++代码如下:

复制代码
#include <iostream>
#include <vector>
#include <string>
using namespace std;

class PizzaType
{
public: 
    enum EPizzaType {cheese,veggie,clam,pepperoni};
};

class PizzaIngredientFactory
{
public:
    virtual string createDough() = 0;
    virtual string createSauce() = 0;
    virtual string createCheese() = 0;
    virtual void createVeggies(vector<string>& vVeggies) = 0;
    virtual string createPepperoni() = 0;
    virtual string createClam() = 0;
};

class NYPizzaIngredientFactory : public PizzaIngredientFactory
{
public:
    string createDough();
    string createSauce();
    string createCheese();
    void createVeggies(vector<string>& vVeggies);
    string createPepperoni();
    string createClam();
};

class ChicagoPizzaIngredientFactory : public PizzaIngredientFactory 
{
public:
    string createDough();
    string createSauce();
    string createCheese();
    void createVeggies(vector<string>& vVeggies);
    string createPepperoni();
    string createClam();
};

class Pizza 
{
public:
    Pizza(PizzaIngredientFactory* pIngredientFactory);
    virtual ~Pizza();
    virtual void prepare() = 0;
    virtual void bake();
    virtual void cut();
    virtual void box();
    string getName();
    void setName(string name);
    vector<string> m_vVeggies;
protected:
    PizzaIngredientFactory* m_pIngredientFactory;
    string m_sName;
    string m_sDough;
    string m_sSauce;
    string m_sCheese;
    string m_sPepperoni;
    string m_sClam;
};

class CheesePizza : public Pizza
{
public:
    CheesePizza(PizzaIngredientFactory* pIngredientFactory):Pizza(pIngredientFactory) {};
    void prepare();
};

class VeggiePizza : public Pizza
{
public:
    VeggiePizza(PizzaIngredientFactory* pIngredientFactory):Pizza(pIngredientFactory) {};
    void prepare();
};

class ClamPizza : public Pizza
{
public:
    ClamPizza(PizzaIngredientFactory* pIngredientFactory):Pizza(pIngredientFactory) {};
    void prepare();
};

class PepperoniPizza : public Pizza
{
public:
    PepperoniPizza(PizzaIngredientFactory* pIngredientFactory):Pizza(pIngredientFactory) {};
    void prepare();
};

class PizzaStore
{
public:
    Pizza* orderPizza(PizzaType::EPizzaType type);
private:
    virtual Pizza* createPizza(PizzaType::EPizzaType type) = 0;
};

class NYPizzaStore : public PizzaStore
{
private:
    Pizza* createPizza(PizzaType::EPizzaType type);
};

class ChicagoPizzaStore : public PizzaStore
{
private:
    Pizza* createPizza(PizzaType::EPizzaType type);
};

string NYPizzaIngredientFactory::createDough()
{
    return "Thin Crust Dough";
}

string NYPizzaIngredientFactory::createSauce()
{
    return "Marinara Sauce";
}

string NYPizzaIngredientFactory::createCheese()
{
    return "Reggiano Cheese";
}

void NYPizzaIngredientFactory::createVeggies(vector<string>& vVeggies)
{
    vVeggies.push_back("Garlic");
    vVeggies.push_back("Onion");
    vVeggies.push_back("Mushrooms");
    vVeggies.push_back("Red Pepper");
}

string NYPizzaIngredientFactory::createPepperoni()
{
    return "Sliced Pepperoni";
}

string NYPizzaIngredientFactory::createClam()
{
    return "Fresh Clams from Long Island Sound";
}

string ChicagoPizzaIngredientFactory::createDough()
{
    return "ThickCrust style extra thick crust dough";
}

string ChicagoPizzaIngredientFactory::createSauce()
{
    return "Tomato sauce with plum tomatoes";
}

string ChicagoPizzaIngredientFactory::createCheese()
{
    return "Shredded Mozzarella";
}

void ChicagoPizzaIngredientFactory::createVeggies(vector<string>& vVeggies)
{
    vVeggies.push_back("Black Olives");
    vVeggies.push_back("Spinach");
    vVeggies.push_back("Eggplant");
}

string ChicagoPizzaIngredientFactory::createPepperoni()
{
    return "Sliced Pepperoni";
}

string ChicagoPizzaIngredientFactory::createClam()
{
    return "Frozen Clams from Chesapeake Bay";
}

Pizza::Pizza(PizzaIngredientFactory* pIngredientFactory)
{
    m_pIngredientFactory = pIngredientFactory;
}

Pizza::~Pizza()
{
    delete m_pIngredientFactory;
}

void Pizza::bake()
{
    printf("Bake for 25 minutes at 350\n");
}

void Pizza::cut()
{
    printf("Cutting the pizza into diagonal slices\n");
}

void Pizza::box()
{
    printf("Place pizza in official PizzaStore box\n");
}

string Pizza::getName()
{
    return m_sName;
}

void Pizza::setName(string name)
{
    m_sName = name;
}

void CheesePizza::prepare()
{
    printf("Preparing %s\n",m_sName.c_str());
    m_sDough = m_pIngredientFactory->createDough();
    m_sSauce = m_pIngredientFactory->createSauce();
    m_sCheese = m_pIngredientFactory->createCheese();
}

void VeggiePizza::prepare()
{
    printf("Preparing %s\n",m_sName.c_str());
    m_sDough = m_pIngredientFactory->createDough();
    m_sSauce = m_pIngredientFactory->createSauce();
    m_sCheese = m_pIngredientFactory->createCheese();
    m_pIngredientFactory->createVeggies(m_vVeggies);
}

void ClamPizza::prepare()
{
    printf("Preparing %s\n",m_sName.c_str());
    m_sDough = m_pIngredientFactory->createDough();
    m_sSauce = m_pIngredientFactory->createSauce();
    m_sCheese = m_pIngredientFactory->createCheese();
    m_sClam = m_pIngredientFactory->createClam();
}

void PepperoniPizza::prepare()
{
    printf("Preparing %s\n",m_sName.c_str());
    m_sDough = m_pIngredientFactory->createDough();
    m_sSauce = m_pIngredientFactory->createSauce();
    m_sCheese = m_pIngredientFactory->createCheese();
    m_pIngredientFactory->createVeggies(m_vVeggies);
    m_sPepperoni = m_pIngredientFactory->createPepperoni();
}

Pizza* PizzaStore::orderPizza(PizzaType::EPizzaType type)
{
    Pizza* pPizza = createPizza(type);
    printf("--- Making a %s ---\n",pPizza->getName().c_str());
    pPizza->prepare();
    pPizza->bake();
    pPizza->cut();
    pPizza->box();
    return pPizza;
}

Pizza* NYPizzaStore::createPizza(PizzaType::EPizzaType type)
{
    Pizza* pPizza = NULL;
    PizzaIngredientFactory* pIngredientFactory = new NYPizzaIngredientFactory();

    if (PizzaType::cheese == type)
    {
        pPizza = new CheesePizza(pIngredientFactory);
        pPizza->setName("New York Style Cheese Pizza");
    }
    else if (PizzaType::veggie == type)
    {
        pPizza = new VeggiePizza(pIngredientFactory);
        pPizza->setName("New York Style Veggie Pizza");
    }
    else if (PizzaType::clam == type)
    {
        pPizza = new ClamPizza(pIngredientFactory);
        pPizza->setName("New York Style Clam Pizza");
    }
    else if (PizzaType::pepperoni == type)
    {
        pPizza = new PepperoniPizza(pIngredientFactory);
        pPizza->setName("New York Style Pepperoni Pizza");
    } 
    return pPizza;
}

Pizza* ChicagoPizzaStore::createPizza(PizzaType::EPizzaType type)
{
    Pizza* pPizza = NULL;
    PizzaIngredientFactory* pIngredientFactory = new ChicagoPizzaIngredientFactory();

    if (PizzaType::cheese == type)
    {
        pPizza = new CheesePizza(pIngredientFactory);
        pPizza->setName("Chicago Style Cheese Pizza");
    }
    else if (PizzaType::veggie == type)
    {
        pPizza = new VeggiePizza(pIngredientFactory);
        pPizza->setName("Chicago Style Veggie Pizza");
    }
    else if (PizzaType::clam == type)
    {
        pPizza = new ClamPizza(pIngredientFactory);
        pPizza->setName("Chicago Style Clam Pizza");
    }
    else if (PizzaType::pepperoni == type)
    {
        pPizza = new PepperoniPizza(pIngredientFactory);
        pPizza->setName("Chicago Style Pepperoni Pizza");
    } 
    return pPizza;
}

int main()
{
    PizzaStore* nyStore = new NYPizzaStore();
    PizzaStore* chicagoStore = new ChicagoPizzaStore();

    Pizza* pizza = nyStore->orderPizza(PizzaType::cheese);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore->orderPizza(PizzaType::cheese);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = nyStore->orderPizza(PizzaType::clam);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore->orderPizza(PizzaType::clam);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = nyStore->orderPizza(PizzaType::pepperoni);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore->orderPizza(PizzaType::pepperoni);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = nyStore->orderPizza(PizzaType::veggie);
    printf("Ethan ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    pizza = chicagoStore->orderPizza(PizzaType::veggie);
    printf("Joel ordered a %s\n",pizza->getName().c_str());
    delete pizza;

    delete nyStore;
    delete chicagoStore;
    return 0;
}
复制代码

 

运行结果如下:

--- Making a New York Style Cheese Pizza ---
Preparing New York Style Cheese Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a New York Style Cheese Pizza
--- Making a Chicago Style Cheese Pizza ---
Preparing Chicago Style Cheese Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Cheese Pizza
--- Making a New York Style Clam Pizza ---
Preparing New York Style Clam Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a New York Style Clam Pizza
--- Making a Chicago Style Clam Pizza ---
Preparing Chicago Style Clam Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Clam Pizza
--- Making a New York Style Pepperoni Pizza ---
Preparing New York Style Pepperoni Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a New York Style Pepperoni Pizza
--- Making a Chicago Style Pepperoni Pizza ---
Preparing Chicago Style Pepperoni Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Pepperoni Pizza
--- Making a New York Style Veggie Pizza ---
Preparing New York Style Veggie Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Ethan ordered a New York Style Veggie Pizza
--- Making a Chicago Style Veggie Pizza ---
Preparing Chicago Style Veggie Pizza
Bake for 25 minutes at 350
Cutting the pizza into diagonal slices
Place pizza in official PizzaStore box
Joel ordered a Chicago Style Veggie Pizza

参考图书:《Head First 设计模式》

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值