C++设计模式笔记(09) - Abstract Factory 抽象工厂



  • 参考课程:《C++设计模式》-李建忠
    李建忠-C++设计模式

1.动机(Motivation)

▷在软件系统中,经常面临着“一系列相互依赖的对象”的创建工作;同时,由于需求的变化,往往存在更多系列对象的创建工作。

▷如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“多系列具体对象创建工作”的紧耦合?

2.模式定义

提供一个接口,让该接口负责创建一系列“相关或者相互依赖的对象”,无需指定它们具体的类。
             ——《设计模式:可复用面向对象软件的基础》

3.结构(Structure)

在这里插入图片描述

4.要点总结

在这里插入图片描述
▷如果没有应对“多系列对象构建”的需求变化,则没有必要使用Abstract Factory模式,这时候使用简单的工厂完全可以。

▷“系列对象”指的是在某一特定系列下的对象之间有相互依赖、或作用的关系。不同系列的对象之间不能相互依赖。

▷Abstract Factory模式主要在于应对“新系列”的需求变动。其缺点在于难以应对“新对象”的需求变动。

5.《Head First 设计模式》实例的C++实现

场景:参照书籍-在建立披萨店之后,我们打算成立分店,建立不同风味的披萨店!       
在这里插入图片描述

  • 抽象原料工厂
//PizzaIngredientFactory.h
//定义抽象原料工厂
//每个原料都对有一个对应的方法创建该原料
#ifndef ABSTRACT_FACTORY_PIZZAINGREDIENTFACTORY_H
#define ABSTRACT_FACTORY_PIZZAINGREDIENTFACTORY_H

#include "Dough.h"
#include "Sauce.h"

class PizzaIngredientFactory {
public:
    PizzaIngredientFactory() = default;
    ~PizzaIngredientFactory() = default;
    virtual Dough* createDough() ;
    virtual Sauce* createSauce() ;
};

#endif //ABSTRACT_FACTORY_PIZZAINGREDIENTFACTORY_H
//PizzaIngredientFactory.cpp

#include "PizzaIngredientFactory.h"

Dough *PizzaIngredientFactory::createDough() {
    return nullptr;
}

Sauce *PizzaIngredientFactory::createSauce() {
}
  • 纽约原料工厂
//NYPizzaIngredientFactory.h
//纽约比萨原料工厂
#ifndef ABSTRACT_FACTORY_NYPIZZAINGREDIENTFACTORY_H
#define ABSTRACT_FACTORY_NYPIZZAINGREDIENTFACTORY_H


#include "PizzaIngredientFactory.h"

class NYPizzaIngredientFactory : public PizzaIngredientFactory{
public:
    NYPizzaIngredientFactory() = default;
    ~NYPizzaIngredientFactory() = default;
    Dough* createDough() override;
    Sauce* createSauce() override;
};

#endif //ABSTRACT_FACTORY_NYPIZZAINGREDIENTFACTORY_H
//NYPizzaIngredientFactory.cpp

#include "NYPizzaIngredientFactory.h"
#include "ThinDough.h"
#include "MarinaraSauce.h"

Dough* NYPizzaIngredientFactory::createDough()  {
    return new ThinDough();
}

Sauce *NYPizzaIngredientFactory::createSauce() {
    return new MarinaraSauce();
}
  • 面团
//Dough.h

#ifndef ABSTRACT_FACTORY_DOUGH_H
#define ABSTRACT_FACTORY_DOUGH_H

class Dough {
public:
    Dough() = default;
    ~Dough() = default;
};

#endif //ABSTRACT_FACTORY_DOUGH_H
//Sauce.h

#ifndef ABSTRACT_FACTORY_SAUCE_H
#define ABSTRACT_FACTORY_SAUCE_H

class Sauce {
public:
    Sauce() = default;
    ~Sauce() = default;
};

#endif //ABSTRACT_FACTORY_SAUCE_H
  • 薄面团
//ThinDough.h

#ifndef ABSTRACT_FACTORY_THINDOUGH_H
#define ABSTRACT_FACTORY_THINDOUGH_H

#include "Dough.h"

class ThinDough : public Dough{
public:
    ThinDough();
    ~ThinDough();
};

#endif //ABSTRACT_FACTORY_THINDOUGH_H
ThinDough.cpp

#include <iostream>
#include "ThinDough.h"

ThinDough::ThinDough() {
    std::cout << "ThinDough材料将准备就绪...完成" << std::endl;
}

ThinDough::~ThinDough() = default;
  • 意式番茄罗勒酱
//MarinaraSauce.h

#ifndef ABSTRACT_FACTORY_MARINARASAUCE_H
#define ABSTRACT_FACTORY_MARINARASAUCE_H

#include "Sauce.h"

class MarinaraSauce : public Sauce{
public:
    MarinaraSauce();
    ~MarinaraSauce() = default;
};

#endif //ABSTRACT_FACTORY_MARINARASAUCE_H
//MarinaraSauce.cpp

#include <iostream>
#include "MarinaraSauce.h"

MarinaraSauce::MarinaraSauce() {
    std::cout << "MarinaraSauce将准备好...完成" << std::endl;
}
  • 抽象比萨类
//Pizza.h
//抽象 比萨 类

#ifndef ABSTRACT_FACTORY_PIZZA_H
#define ABSTRACT_FACTORY_PIZZA_H

#include <string>
#include "Dough.h"
#include "Sauce.h"
#include "PizzaIngredientFactory.h"

class Pizza {
public:
    std::string name;
    Dough* dough{};
    Sauce* sauce{};

    Pizza() = default;
    ~Pizza() = default;

    virtual void prepare();
    virtual void bake();
    virtual void cut();
    virtual void box();
    std::string getName();
    void setName(std::string n_name);
    static std::string toStr();    //这是打印比萨的代码
};

#endif //ABSTRACT_FACTORY_PIZZA_H
//Pizza.cpp

#include "Pizza.h"
#include <iostream>
#include <utility>

void Pizza::bake() {
    std::cout << "在350烘烤25分钟" << std::endl;
}

void Pizza::cut() {
    std::cout << "将比萨切成对角" << std::endl;
}

void Pizza::box() {
    std::cout << "将比萨放入比萨店的官方包装盒" << std::endl;
}

std::string Pizza::getName() {
    return name;
}

void Pizza::setName(std::string n_name) {
    this->name = std::move(n_name);
}

std::string Pizza::toStr() {
    return "";
}

void Pizza::prepare() {
}
  • 芝士比萨
//CheesePizza.h
#ifndef ABSTRACT_FACTORY_CHEESEPIZZA_H
#define ABSTRACT_FACTORY_CHEESEPIZZA_H

#include "Pizza.h"

class CheesePizza : public Pizza{
public:
    CheesePizza() = default;
    ~CheesePizza() = default;
    explicit CheesePizza(PizzaIngredientFactory* i_ingredientFactory);
    void prepare() override ;

private:
    PizzaIngredientFactory* ingredientFactory{};
};

#endif //ABSTRACT_FACTORY_CHEESEPIZZA_H
//CheesePizza.cpp

#include <iostream>
#include "CheesePizza.h"

CheesePizza::CheesePizza(PizzaIngredientFactory* i_ingredientFactory)
{
    this->ingredientFactory = i_ingredientFactory;
}

void CheesePizza::prepare() {
    std::cout << "准备 " << name << std::endl;
    dough = ingredientFactory->createDough();
    sauce = ingredientFactory->createSauce();
}
  • 抽象 比萨店 类
//NYPizzaStore.h

#ifndef ABSTRACT_FACTORY_NYPIZZASTORE_H
#define ABSTRACT_FACTORY_NYPIZZASTORE_H

#include "PizzaStore.h"
#include <string>

class NYPizzaStore : public PizzaStore{
public:
    NYPizzaStore() = default;
    ~NYPizzaStore() = default;
    Pizza* createPizza(std::string type) override;
};

#endif //ABSTRACT_FACTO
//NYPizzaStore.cpp

#include "NYPizzaStore.h"
#include "PizzaIngredientFactory.h"
#include "NYPizzaIngredientFactory.h"
#include "CheesePizza.h"

Pizza* NYPizzaStore::createPizza(std::string type) {
    Pizza* pizza = nullptr;
    PizzaIngredientFactory* ingredientFactory = new NYPizzaIngredientFactory();

    if(type == "cheese"){
        pizza = new CheesePizza(ingredientFactory);
        pizza->setName("纽约风格奶酪比萨饼");
    }
    return pizza;
}
  • 纽约比萨店
//NYPizzaStore.h

#ifndef ABSTRACT_FACTORY_NYPIZZASTORE_H
#define ABSTRACT_FACTORY_NYPIZZASTORE_H

#include "PizzaStore.h"
#include <string>

class NYPizzaStore : public PizzaStore{
public:
    NYPizzaStore() = default;
    ~NYPizzaStore() = default;
    Pizza* createPizza(std::string type) override;
};

#endif //ABSTRACT_FACTO
//NYPizzaStore.cpp

#include "NYPizzaStore.h"
#include "PizzaIngredientFactory.h"
#include "NYPizzaIngredientFactory.h"
#include "CheesePizza.h"

Pizza* NYPizzaStore::createPizza(std::string type) {
    Pizza* pizza = nullptr;
    PizzaIngredientFactory* ingredientFactory = new NYPizzaIngredientFactory();

    if(type == "cheese"){
        pizza = new CheesePizza(ingredientFactory);
        pizza->setName("纽约风格奶酪比萨饼");
    }
    return pizza;
}
  • 测试
//main.cpp
#include <iostream>
#include "NYPizzaStore.h"

int main() {
    PizzaStore* NYPizzaStore = new class NYPizzaStore();
    NYPizzaStore->oderPizza("cheese");
}
  • 显示结果:
    在这里插入图片描述

欢迎关注公众号:c_302888524
发送:“设计模式:可复用面向对象软件的基础” 获取电子书
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值