> 技术文档 > 深入浅出设计模式——创建型模式之简单工厂模式

深入浅出设计模式——创建型模式之简单工厂模式


文章目录

  • 设计模式的六大原则 Six principles
  • 简单工厂模式
    • 简单工厂基本实现流程
    • 简单工厂定义
    • 代码结构如下:
  • 简单工厂模式代码实例
    • 定义抽象产品类AbstractProduct,抽象方法不提供实现
    • 定义三个具体产品类
    • 定义工厂类和工厂方法
    • 客户端使用方法示例
    • 效果
    • SimpleFactory.h
    • main.cpp
    • 运行结果
  • 简单工厂模式总结

代码仓库在这

设计模式在面试中的考点通常是介绍其原理并说出优缺点。或者对比几个比较相似的模式的异同点。在笔试中可能会出现画出某个设计模式的 UML 图这样的题。虽说面试中占的比重不大,但并不代表它不重要。恰恰相反,设计模式于程序员而言相当重要,它是我们写出优秀程序的保障。设计模式与程序员的架构能力与阅读源码的能力息息相关,非常值得我们深入学习。

面向对象的特点是 可维护、可复用、可扩展、灵活性好,它最强大的地方在于:随着业务变得越来越复杂,面向对象依然能够使得程序结构良好,而面向过程却会导致程序越来越臃肿。

让面向对象保持结构良好的秘诀就是设计模式,面向对象结合设计模式,才能真正体会到程序变得可维护、可复用、可扩展、灵活性好。设计模式对于程序员而言并不陌生,每个程序员在编程时都会或多或少的接触到设计模式。无论是在大型程序的架构中,亦或是在源码的学习中,设计模式都扮演着非常重要的角色。

今天我们就一起来探索设计模式的世界!

设计模式的六大原则 Six principles

设计模式的世界丰富多彩,比如生产一个个“产品”的工厂模式,衔接两个不相关接口的适配器模式,用不同的方式做同一件事的策略模式,构建步骤稳定、根据构建过程的不同配置构建出不同对象的建造者模式等等。

无论何种设计模式,都是基于六大设计原则:

在这里插入图片描述

简单工厂模式

创建型模式关注对象的创建过程,在软件开发中应用非常广泛。创建型模式描述如何将对象的创建和使用分离,让用户在使用对象过程中无须关心对象的创建细节,从而降低系统耦合度,并且让系统易于修改和扩展。

在这里插入图片描述
什么是简单工厂模式呢?举个例子:如上图,一个体育用品生产厂(这即是一个工厂Factory),该工厂可以根据客户需求生产篮球、足球和排球。篮球、足球和排球被成为产品(Product),产品的名称可以被成为参数。客户Jungle需要时可以向工厂提供产品参数,工厂根据产品参数生产对应产品,客户Jungle并不需要关心产品的生产过程细节。

简单工厂模式是最简单的设计模式之一,其实它并不属于Gof的23种设计模式,但应用也十分频繁,同时也是其余创建模式的基础,因此有必要先学习简单工厂模式。

在平时编程中,构建对象最常用的方式是 new 一个对象。乍一看这种做法没什么不好,而实际上这也属于一种硬编码。每 new 一个对象,相当于调用者多知道了一个类,增加了类与类之间的联系,不利于程序的松耦合。其实构建过程可以被封装起来,工厂模式便是用于封装对象的设计模式。

举个例子,直接 new 对象的方式相当于当我们需要一个苹果时,我们需要知道苹果的构造方法,需要一个梨子时,需要知道梨子的构造方法。更好的实现方式是有一个水果工厂,我们告诉工厂需要什么种类的水果,水果工厂将我们需要的水果制造出来给我们就可以了。这样我们就无需知道苹果、梨子是怎么种出来的,只用和水果工厂打交道即可。

事实上,将构建过程封装的好处不仅可以降低耦合,如果某个产品构造方法相当复杂,使用工厂模式可以大大减少代码重复

简单工厂基本实现流程

在这里插入图片描述

简单工厂定义

定义一个简单工厂类,它可以根据参数的不同返回不同类的实例,被创建的实例通常都具有共同的父类
在这里插入图片描述

在这里插入图片描述

代码结构如下:

//抽象产品类AbstractProductclass AbstractProduct{public://抽象方法:}; //具体产品类Basketballclass ConcreteProduct :public AbstractProduct{public://具体实现方法}; class Factory{public:AbstractProduct createProduct(string productName){AbstractProduct pro = NULL;if (productName == \"ProductA\"){pro = new ProductA();}else if (productName == \"ProductB\"){pro = new ProductB();}...}};

客户端在使用时,只需要创建一个工厂对象,调用工厂对象的createProduct方法,并传入所需要的产品参数,即可得到所需产品实例对象,而无需关心产品的创建细节。

简单工厂模式代码实例

考虑有以下一个场景:
Jungle想要进行户外运动,它可以选择打篮球、踢足球或者玩排球。它需要凭票去体育保管室拿,票上写着一个具体球类运动的名字,比如“篮球”。体育保管室负责人根据票上的字提供相应的体育用品。然后Jungle就可以愉快地玩耍了。

我们采用简单工厂模式来实现上述场景。首先,体育保管室是工厂,篮球、足球和排球是具体的产品,而抽象产品可以定义为“运动球类产品SportProduct”.Jungle作为客户只需要提供具体产品名字,工厂就可“生产”出对应产品。

定义抽象产品类AbstractProduct,抽象方法不提供实现

//抽象产品类AbstractProductclass AbstractSportProduct{public:AbstractSportProduct(){ }//抽象方法:void printName(){};void play(){};};

定义三个具体产品类

//具体产品类Basketballclass Basketball :public AbstractSportProduct{public:Basketball(){printName();play();}//具体实现方法void printName(){printf(\"Jungle get Basketball\\n\");}void play(){printf(\"Jungle play Basketball\\n\");}}; //具体产品类Footballclass Football :public AbstractSportProduct{public:Football(){printName();play();}//具体实现方法void printName(){printf(\"Jungle get Football\\n\");}void play(){printf(\"Jungle play Football\\n\");}}; //具体产品类Volleyballclass Volleyball :public AbstractSportProduct{public:Volleyball(){printName();play();}//具体实现方法void printName(){printf(\"Jungle get Volleyball\\n\");}void play(){printf(\"Jungle play Volleyball\\n\");}};

定义工厂类和工厂方法

class Factory{public:AbstractSportProduct *getSportProduct(string productName){AbstractSportProduct *pro = NULL;if (productName == \"Basketball\"){pro = new Basketball();}else if (productName == \"Football\"){pro = new Football();}else if (productName == \"Volleyball\"){pro = new Volleyball();}return pro;}};

客户端使用方法示例

#include #include \"SimpleFactory.h\" int main(){ printf(\"简单工厂模式\\n\"); //定义工厂类对象 Factory *fac = new Factory(); AbstractSportProduct *product = nullptr; product = fac->getSportProduct(\"Basketball\"); delete product; product = nullptr; product = fac->getSportProduct(\"Football\"); delete product; product = nullptr; product = fac->getSportProduct(\"Volleyball\"); delete product; product = nullptr; system(\"pause\"); delete fac; fac = nullptr; return 0;}

效果

在这里插入图片描述

可以看到,在客户端使用时,只需要提供产品名称作为参数,传入工厂的方法中,即可得到对应产品。抽象产品类中并没有提供公共方法的实现,而是在各个具体产品类中根据各自产品情况实现。

SimpleFactory.h

#ifndef __SIMPLE_FACTORY__#define __SIMPLE_FACTORY__#include #include using namespace std;//抽象产品类AbstractProductclass AbstractSportProduct {public: AbstractSportProduct(){} virtual ~AbstractSportProduct(){} //抽象方法:// virtual void printName(){}; // printName() 是一个纯虚函数,表示每个具体的产品(具体的运动产品)必须实现的接口方法。纯虚函数由 = 0 来标记,意味着该函数没有实现,必须由继承该类的子类来提供实现。 virtual void printName() = 0; // virtual void play(){}; virtual void play() = 0;};//具体产品类Basketballclass Basketball :public AbstractSportProduct {public:Basketball(){printName();play();}~Basketball() {}//具体实现方法void printName(){printf(\"Jungle get Basketball\\n\");}void play(){printf(\"Jungle play Basketball\\n\");}};//具体产品类Footballclass Football :public AbstractSportProduct {public:Football(){printName();play();}~Football() {}//具体实现方法void printName(){printf(\"Jungle get Football\\n\");}void play(){printf(\"Jungle play Football\\n\");}};//具体产品类Volleyballclass Volleyball :public AbstractSportProduct {public:Volleyball(){printName();play();}~Volleyball() {}//具体实现方法void printName(){printf(\"Jungle get Volleyball\\n\");}void play(){printf(\"Jungle play Volleyball\\n\");}};class Factory {public: std::shared_ptr<AbstractSportProduct> getSportProduct(string productName) { std::shared_ptr<AbstractSportProduct> pro; if(productName == \"Basketball\") { pro = std::shared_ptr<AbstractSportProduct>(new Basketball()); } else if(productName == \"Football\"){pro = std::shared_ptr<AbstractSportProduct>(new Football());}else if (productName == \"Volleyball\"){pro = std::shared_ptr<AbstractSportProduct>(new Volleyball());}return pro; }};#endif //__SIMPLE_FACTORY__

main.cpp

#include #include #include \"SimpleFactory.h\"int main() { printf(\"简单工厂模式\\n\");//定义工厂类对象 std::shared_ptr<Factory> fac = std::make_shared<Factory>(); // std::shared_ptr product = std::shared_ptr(fac->getSportProduct(\"Basketball\")); std::shared_ptr<AbstractSportProduct> product = fac->getSportProduct(\"Basketball\"); fac = std::make_shared<Factory>(); product = fac->getSportProduct(\"Football\"); // product = std::shared_ptr(fac->getSportProduct(\"Football\"));fac = std::make_shared<Factory>();product = fac->getSportProduct(\"Volleyball\");// product = std::shared_ptr(fac->getSportProduct(\"Volleyball\"));// 这段代码仅在 Windows 平台下执行。在 Windows 环境中,system(\"pause\") 会暂停程序的执行,并在控制台输出 \"Press any key to continue...\",等待用户按任意键继续。这个代码片段在 Windows 下有用,但在其他操作系统中没有影响。#ifdef win32 system(\"pause\");#endif  return 0;}

运行结果

在这里插入图片描述

在这里插入图片描述

简单工厂模式总结

在这里插入图片描述

在这里插入图片描述

之后我会持续更新,如果喜欢我的文章,请记得一键三连哦,点赞关注收藏,你的每一个赞每一份关注每一次收藏都将是我前进路上的无限动力 !!!↖(▔▽▔)↗感谢支持!