工厂模式

三种类型

  • 简单工厂模式

  • 工厂方法模式

  • 抽象工厂模式

🌰

所有工厂模式核心

核心将对象new的过程,改为向工厂索取

  • 业务层:负责使用对象,用不写new

  • 工厂层:负责创建对象,所有实例化对象逻辑都在这

  • 优点:开闭原则1 ,里氏替换原则2

  • 所有产品类继承自同一个基类、纯虚函数,所有工厂类继承同一个工厂基类/纯虚函数,全程使用多态

[footnotes]  :(新增产品,只改工厂,不该业务)

[2]  子类可以完全实现父类

简单工厂模式

不是 GOF23 种正式设计模式,是工厂模式的基础,也叫「静态工厂模式」,是 C++ 最常用的入门工厂;

核心:一个工厂类 + 一个判断逻辑,工厂类里写一个「静态创建方法」,通过传入的字符串 / 枚举参数,用 if/switch 判断,创建并返回不同的产品对象;

所有产品都继承同一个基类,返回值是基类指针 / 引用(C++ 多态的核心体现)。

☑️特征

一个万能工厂,生产所有类,靠参数决定生产什么

🌰

 #include <iostream>
 #include <string>品的 while 循环里 int num = 0; 写在循环体内 → 每次循环都重置,死循环!把 num 提出循环外或干脆用 for
 using namespace std;
 // =======第一步:定义【产品基类】- 所有机器人的统一规范(抽象类) =====
 class R{
     public:
     //纯虚函数,all robot must 实现生成机器人这个行为
     virtual void makeR() = 0;
     //析构虚函数,C++继承必须写,防止内存泄漏
     virtual ~R(){}
 };
 // ======第二步:定义【具体惨产品子类】- 继承产品基类 ====
 // 榆树机器人产品
 class YS : public R{
     void makeR() override{//重写基类纯虚函数
         bool ys = 0;
         int num = 0;
         while(!ys){
 ​
             num++;
             if(num == 520){
                 ys = 1;
                 num = 0;
             }    
         }
     }
 };
 // 云深处机器人产品
 class YSC : public R{
     void makeR() override{//重写基类纯虚函数
         bool ysc = 0;
         int num = 0;
         while(!ysc){
 ​
             num++;
             if(num == 520){
                 ysc = 1;
                 num = 0;
             }    
         }
     }
 };
 // ====== 第三步: 核心 - 唯一的【简单工厂类】 ====
 class RFty{
     public:
     //静态创建方法:传参数,返回产品基类指针
     static R* buildR(string name){
         R* r = nullptr;
         //根据传入参数,创建对应产品
         if(name == "宇"){
             r = new YS;
         }
         else if(name == "云"){
             r = new YSC;
         }
         return r;
     }
 };
 // ====== 测试: 业务层代码(只使用不创建) ====
 int main(){
     //要榆树机器人,只要给工厂发送索求,拿到基类指针
     R* ys = RFty::buildR("宇");
     ys->makeR(); //多态调用
     
     //要云生出机器人,只要给工厂发送索求,拿到基类指针
     R* ysc = RFty::buildR("云");
     ysc->makeR(); //多态调用
     
     //手动释放堆内存
     delete ys;
     delete ysc;
     ys = nullptr;
     ysc = nullptr;
     return 0;
 }

极简,易用,代码量少

🚨违反开闭原则,如增加纵情机器人,必须修改工厂类的if判断逻辑,工厂会越来越臃肿

工厂方法模式(Factory Method Pattern)

GOF23 种正式设计模式,是简单工厂的「升级版」,解决了简单工厂违反开闭原则的核心痛点;

核心 : 定义抽象工厂类(纯虚类),只声明创建产品的纯虚方法,不实现具体逻辑;每个具体产品,都对应一个专属具体工厂子类

逻辑创建时延迟到具体工厂子类中实现,不再if/swich判断;

C++核心:抽象工厂的纯虚方法返回产品基类指针,具体实现工厂重写该方法,返回对应产品指针,全程多态

特征 一个产品一个专属工厂,各管各的,无万能工厂

🌰

 #include <iostream>
 using namespace std;
 // ====== 第一步:产品【产品基类】 - 所有机器人统一规范 ====
 class R{
     public:
     virtual void makeR() = 0;
     virtual ~R(){}
 };
 // ======具体:榆树  ====
 class ys : public R{
     void makeR() override{
         int num = 0;
         bool ys = false;
         while(!ys){
          num++;
             if(num == 77){
                 ys = true;
                 num = 0;
             }    
         }
     }
 };
 // ======具体:云深处 ====
 class ysc : public R{
     void makeR() override{
         int num = 0;
         bool ysc = false;
         while(!ysc){
             num++;
             if(num == 77){
                 ysc = true;
                 num = 0;
             }    
         }
     }
 };
 // ====== 第二步: 核心1 -定义【抽象工厂类】纯虚函数 ====
 //只规定每个厂有找机器人能力,不写具体实现
 class AbstractFty{
     public:
     virtual R* buildR() = 0; //纯虚函数创建方法
     virtual ~AbstractFty(){}
 };
 // ====== 第三步 核心2 -每个产品对应一个厂【具体】 ====
 //榆树厂:只做机器人专属工厂
 class ysfty : public AbstractFty{
     public:
     R* buildR() override{
         return new ys;
     }
 };
 //云深处厂:只做机器人专属工厂
 class yscfty : public AbstractFty{
     public:
     R* buildR() override{
         return new ysc;
     }
 };
 // ====== 测试: 业务层代码 ====
 int main(){
     //需求1 要榆树机器人 -> 创建榆树厂,调用厂的实现方法
     AbstractFty* YsFty = new ysfty;
     R* ysr = YsFty->buildR();
     ysr->makeR();
     //需求1 要云深处机器人 -> 创建云深处厂,调用厂的实现方法
     AbstractFty* YscFty = new yscfty;
     R* yscr = YscFty->buildR();
     yscr->makeR();
     delete ysr;
     delete yscr;
     delete YsFty;
     delete YscFty;
     return 0;
 }

✅完美遵循开闭原则!如果要增加【纵情机器人】,只需两件事

  • 新增 zq类,继承R并重写makeR();

  • 新增zqfty类, 继承AbstractFty并重写buildR();

🚨类数量翻倍,产品越多。类越多,越复杂。而且只能生产单一产品,不能生产【成套产品】(比如人形机器人和四足机器人)

抽象工厂(Abstract Factory Pattern)

GOF23 种正式设计模式,是工厂方法的「终极升级版」,也是 C++ 中解耦性最强的工厂模式;

核心: 一个抽象工厂接口,用于创建一系列相关产品族,而无需制定他们的类

两个概念

  • 产品等级结构: 同一种产品的【基类+子类】,比如人形基类+榆树人形机器人+云深处机器人是一个产品等级,四足基类+榆树机器狗+云深处机器狗是一个产品等级。

  • 产品族: 同一个品牌/同一家工厂生产的,配套使用的不同产品,比如【榆树机器人加榆树机器狗】是榆树产品族,...

特征 一个工厂生产一套产品,不生产单一产品

🌰

 #include <iostream>
 using namespace std;
 ​
 // ======= 第一步: 定义 【两个产品等级结构】 ====
 // 产品等级1: 人形产品的基类(抽象)
 class R{
     public:
     virtual void makeR() = 0;
     virtual ~R(){}
 };
 // 榆树人形 (属于榆树产品族)
 class ysr : public R{
     void makeR() override{
         int num = 0;
         bool ysr = false;
         while(!ysr){
             num++;
             if(num == 99){
                 num = 0;
                 ysr = true;
             }
         }
     }
 };
 // 云深处人形 (属于云深处产品族)
 class yscr : public R{
     void makeR() override{
         int num = 0;
         bool yscr = false;
         while(!yscr){
             num++;
             if(num == 99){
                 num = 0;
                 yscr = true;
             }
         }
     }
 };
 // 产品等级2: 机器狗的基类(抽象)
 class D{
     public:
     virtual void makeD() = 0;
     virtual ~D(){}
 };
 // 榆树狗 (属于榆树产品族)
 class ysd : public D{
     void makeD() override{
         int num = 0;
         bool ysd = false;
         while(!ysd){
             num++;
             if(num == 99){
                 num = 0;
                 ysd = true;
             }
         }
     }
 };
 // 云深处狗 (属于云深处产品族)
 class yscd : public D{
     void makeD() override{
         int num = 0;
         bool yscd = false;
         while(!yscd){
             num++;
             if(num == 99){
                 num = 0;
                 yscd = true;
             }
         }
     }
 };
 // ====== 核心 - 定义【抽象工厂类】 ====
 //抽象工厂:规定【产品族】的所有产品创建方法
 //要求所有厂都能生产人形和机器狗这一套产品
 class AbsFty{
     public:
     virtual R* buildR() = 0;
     virtual D* buildD() = 0;
     virtual ~AbsFty(){}
 };
 // ====== 定义:【具体工厂类】 - 一个工厂对应一个产品族 =====
 //榆树工厂 只生产所有榆树产品 人形 + 机器狗
 class ysfty : public AbsFty{
     public:
     R* buildR() override{
         return new ysr;
     }
     D* buildD() override{
         return new ysd;
     }
 };
 //云深处工厂 只生产所有云深处产品 人形 + 机器狗
 class yscfty : public AbsFty{
     public:
     R* buildR() override{
         return new yscr;
     }
     D* buildD() override{
         return new yscd;
     }
 };
 ​
 // =======测试 业务代码 ===
 int main(){
     //需求1。 我要一套榆树产品, -> 创建榆树工厂
     AbsFty* Ysfty = new ysfty;
     R* Ys = Ysfty->buildR();
     D* Ysd = Ysfty->buildD();
     Ys->makeR();
     Ysd->makeD();
     //需求2。 我要一套云深处产品, -> 创建云深处工厂
     AbsFty* Yscfty = new yscfty;
     R* Ysc = Yscfty->buildR();
     D* Yscd = Yscfty->buildD();
     Ysc->makeR();
     Yscd->makeD();
     
     delete Ys; delete Ysd; delete Ysfty;
     delete Ysc; delete Yscd; delete Yscfty;
     return 0;
 }
Logo

DAMO开发者矩阵,由阿里巴巴达摩院和中国互联网协会联合发起,致力于探讨最前沿的技术趋势与应用成果,搭建高质量的交流与分享平台,推动技术创新与产业应用链接,围绕“人工智能与新型计算”构建开放共享的开发者生态。

更多推荐