当前位置: 首页 > news >正文

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

文章目录

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

代码仓库在这

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

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

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

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

设计模式的六大原则 Six principles

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

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

在这里插入图片描述

简单工厂模式

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

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

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

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

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

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

简单工厂基本实现流程

在这里插入图片描述

简单工厂定义

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

在这里插入图片描述

代码结构如下:

//抽象产品类AbstractProduct
class AbstractProduct
{
public://抽象方法:
};//具体产品类Basketball
class 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,抽象方法不提供实现

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

定义三个具体产品类

//具体产品类Basketball
class Basketball :public AbstractSportProduct
{
public:Basketball(){printName();play();}//具体实现方法void printName(){printf("Jungle get Basketball\n");}void play(){printf("Jungle play Basketball\n");}
};//具体产品类Football
class Football :public AbstractSportProduct
{
public:Football(){printName();play();}//具体实现方法void printName(){printf("Jungle get Football\n");}void play(){printf("Jungle play Football\n");}
};//具体产品类Volleyball
class 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 <iostream>
#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 <iostream>
#include <string.h>
using namespace std;//抽象产品类AbstractProduct
class AbstractSportProduct {
public:AbstractSportProduct(){}virtual ~AbstractSportProduct(){}//抽象方法:// virtual void printName(){};// printName() 是一个纯虚函数,表示每个具体的产品(具体的运动产品)必须实现的接口方法。纯虚函数由 = 0 来标记,意味着该函数没有实现,必须由继承该类的子类来提供实现。virtual void printName() = 0;// virtual void play(){};virtual void play() = 0;
};//具体产品类Basketball
class Basketball :public AbstractSportProduct {
public:Basketball(){printName();play();}~Basketball() {}//具体实现方法void printName(){printf("Jungle get Basketball\n");}void play(){printf("Jungle play Basketball\n");}
};//具体产品类Football
class Football :public AbstractSportProduct {
public:Football(){printName();play();}~Football() {}//具体实现方法void printName(){printf("Jungle get Football\n");}void play(){printf("Jungle play Football\n");}
};//具体产品类Volleyball
class 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 <iostream>
#include <memory>
#include "SimpleFactory.h"int main() {printf("简单工厂模式\n");//定义工厂类对象std::shared_ptr<Factory> fac = std::make_shared<Factory>();// std::shared_ptr<AbstractSportProduct> product = std::shared_ptr<AbstractSportProduct>(fac->getSportProduct("Basketball"));std::shared_ptr<AbstractSportProduct> product = fac->getSportProduct("Basketball");fac = std::make_shared<Factory>();product = fac->getSportProduct("Football");// product = std::shared_ptr<AbstractSportProduct>(fac->getSportProduct("Football"));fac = std::make_shared<Factory>();product = fac->getSportProduct("Volleyball");	// product = std::shared_ptr<AbstractSportProduct>(fac->getSportProduct("Volleyball"));	// 这段代码仅在 Windows 平台下执行。在 Windows 环境中,system("pause") 会暂停程序的执行,并在控制台输出 "Press any key to continue...",等待用户按任意键继续。这个代码片段在 Windows 下有用,但在其他操作系统中没有影响。
#ifdef win32system("pause");
#endif  return 0;
}

运行结果

在这里插入图片描述

在这里插入图片描述

简单工厂模式总结

在这里插入图片描述

在这里插入图片描述

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

http://www.dtcms.com/a/298175.html

相关文章:

  • Spring Cache
  • Allegro软件光绘文件Artwork到底如何配置?
  • python+pandas是否能代替excel+vba?
  • C 标准库 <time.h> 函数详解
  • [ComfyUI] -入门2- 小白零基础搭建ComfyUI图像生成环境教程
  • 暑期算法训练.8
  • FastDFS如何提供HTTP访问电子影像文件
  • 海外短剧系统源码交付全解析:技术架构与全球化部署实战
  • 第十节 点阵屏模块
  • 案例分享|告别传统PDA+便携打印机模式,快速实现高效率贴标
  • 构建未来照护力量:虚拟仿真养老实训室的技能评估新体系
  • 常见主流网格孔洞修补算法(Mesh Hole Filling)汇总
  • 【Spring WebFlux】为什么 Spring 要拥抱响应式
  • 产业聚集+顶级配套 成都国际数字影像产业园打造企业战略增长极
  • DuoPlus云手机再上新:统一配置品牌型号、代理分组与便捷搜索功能全面提升!
  • 易求职 - 求职难题全方位解决方案
  • Android 图像编辑实战指南:从基础操作到进阶效果
  • 网络协议,DHCP 协议等。
  • 14-C语言:第14天笔记
  • C++ 笔记
  • 在Word和WPS文字中添加的拼音放到文字右边
  • 二分查找----6.寻找两个正序数组的中位数
  • CIU32L051 DMA+Lwrb环形队列实现串口无阻塞性数据的收发 + 数据百分百不丢失的实现
  • docker-compose up -d 显示no configuration file provided: not found什么问题
  • SSM花店花卉管理系统—计算机毕业设计源码—27787
  • 重构 MVC:让经典架构完美适配复杂智能系统的后端业务逻辑层(内附框架示例代码)
  • 全国产化5G-A低空经济基座
  • 基础很薄弱如何规划考研
  • 【实操记录】docker hello world
  • lesson24:Python的logging模块