工厂模式有三种,分别是:简单工厂模式,工厂模式,抽象工厂模式

要理解为什么要用工厂模式,首先我们要这样编程:例如一家游戏公司已经写好了 飞机类文件,坦克类文件,潜艇类文件,并把他们封装好让程序员们来调用(姑且把封装好的文件叫库文件),而程序员调用来写程序,姑且把程序员叫做使用者。好,理解这句话我们就继续往下说。

无论哪种工厂模式,都不会给你直接 new 具体的产品对象的。使用者能做的只是操作两个接口--->抽象产品对象和抽象工厂对象。那这里又怎么理解呢?

以战争游戏为例,使用工厂模式的话,调用者(一般调用库文件写main的程序员)不能直接 new(创建) 出坦克对象或者飞机对象,他能new的只是一个武器对象(抽象产品类),然后通过对武器对象(抽象产品类)操作,来获得一个具体的武器对象,如坦克对象,如飞机对象,这里用的操作方法就是多态了,所以工厂模式处处都有多态。

而抽象工厂也是同样理解,工厂生成产品,所以这里我们可以把抽象工厂类看成一个武器车间对象,根据使用者(程序员)的操作,可以通过多态把武器车间设置成坦克车间对象,飞机车间对象。而记住,程序员是不可以直接 new出坦克车间的,这是工厂模式设计出来所避免的东西。

看到这里,相信大家会有疑问,为什么就不允许直接 new 出坦克对象,飞机对象等具体的对象呢?

因为试想一下,一个战争游戏,只有一个车间,步兵从那里出,坦克从那里出,飞机从那里出,造成的后果就是大量的代码混杂在一起,增加维护难度。

而且设计模式有一个原则就是面向接口编程,倾向于把一切封装起来,只露出接口,这样的好处是代码管理,维护方便。

下面介绍简单工厂模式:简单工厂模式一般比较少用,因为本身有较大缺点。其优点就是不用记那么多类名,只要传入对应表示参数就能创建对应类了,

例如1表示坦克,就参数type=1,2等于飞机,就type=2,等待再讲缺点在哪

简单工厂模式:

简单工厂一般向工厂对象传入参数type来决定生产哪种产品。

#include<iostream>
using namespace std;/*以战争游戏为例*/
class AbstractProduct  //抽象武器类
{public:virtual void operation()=0;
} ;class AbstractFactory    //抽象车间
{public:virtual AbstractProduct *createproduct(int type)=0;
};class ProductA:public AbstractProduct //坦克类
{public:void operation(){cout<<"this is ProductA"<<endl;}
};class ProductB:public AbstractProduct //飞机类
{public:void operation(){cout<<"this is productB"<<endl;}
};/*大武器车间,其实这里不用抽象工厂也行,直接用SimpleFactory类也可以
但是设计模式都要抽象,所以按规矩就写一下抽象工程类。*/
class SimpleFactory:public AbstractFactory
{public:AbstractProduct *createproduct(int type){if(type == 1)return new ProductA();if(type == 2)return new ProductB();}
};int main()
{AbstractProduct *p = NULL;AbstractFactory *f = NULL;f = new SimpleFactory();p = f->createproduct(1);    //当type=1时,创建产品A对象,type=2,创建产品B p->operation();return 0;
}

为什么说简单工厂模式一般不用,因为它违反了设计模式的 开闭原则。

什么叫开闭原则呢?

就是对代码模块,允许扩展,就是增加代码量,但现在的代码不允许修改。

想想简单工厂模式,如果我要增加导弹类武器,怎么办?只能修改SimpleFactory类中的代码,增加 if(type=3),就new一个导弹类。

这本质上修改了SimpleFactory代码模块。下面要讲的第二种工厂模式---工厂模式就可以解决这个问题。

工厂模式:

#include<iostream>
using namespace std;class AbstractWeapon            //抽象武器类
{public:virtual void operation()=0;
};class J10:public AbstractWeapon       //J10战斗机
{public:void operation(){cout<<"this is J10"<<endl;}
};class F22:public AbstractWeapon       //F22战斗机
{public:void operation(){cout<<"this is F22"<<endl;}
};class Tank1:public AbstractWeapon //一号坦克
{public:void operation(){cout<<"this is T1"<<endl;}
};///
class AbstractFactory               //抽象工厂
{public:virtual AbstractWeapon *create1()=0;   virtual AbstractWeapon *create2()=0;
};class PlaneFactory:public AbstractFactory //飞机工厂
{public:AbstractWeapon *create1(){return new J10();     }   AbstractWeapon *create2(){return new F22();}
};class TankFactory:public AbstractFactory  //坦克工厂
{public:AbstractWeapon *create1(){return new Tank1();}  AbstractWeapon *create2(){}
};int main()
{AbstractWeapon *p=NULL;AbstractFactory *f = NULL;f = new TankFactory();     //选择坦克工厂 //f = new PlaneFactory;    //选择飞机工厂 p = f->create1();p->operation();return 0;
}
/*打印结果:This is T1*/ 

由上面代码可知,通过增加多态的代码,可以扩展多一种工厂来生产新一类产品,从而不需要改动原来的代码模块,因为当你的代码量多的话,轻易改代码模块是很高风险的。上面的抽象工厂类相当于所有具体工厂的规格要求,如上,我在抽象工厂定义了2个纯虚函数用于创建对象,就是说,所有的具体工厂最多只能创建2种不同的武器,如(J10,F22),当然一种也可以,如坦克类就只有一号坦克。你想创建多种不同的武器,往抽象类中加纯虚函数即可

但这种工厂模式也是有缺陷的,就是一种工厂只能生产一类产品,如飞机工厂,只能生成各种飞机。

相信大家都玩过红色境界,例如现在有中美两个国家,中国有自己的飞机坦克,美国也有自己的飞机坦克,那我们实现的时候,绝不能在美国工厂能生成中国工厂的东西。

而抽象工厂模式能有一个更好的分类功能

抽象工厂模式:

抽象工厂可以使一类工厂生产不同类的的产品,但这些产品都有一定的联系。

#include<iostream>
using namespace std;class AbstractPlane         //抽象飞机类
{public:virtual void operation()=0;
};class J10:public AbstractPlane    //中国J10战斗机
{public:void operation(){cout<<"this is J10"<<endl;}
};class F22:public AbstractPlane    //美国F22战斗机
{public:void operation(){cout<<"this is F22"<<endl;}
};
//
class AbstractTank          //抽象坦克类
{public:virtual void operation()=0;
};class China_Tank:public AbstractTank  //中国坦克
{public:void operation(){cout<<"this is china tank"<<endl;}
};class USA_Tank:public AbstractTank        //美国坦克
{public:void operation(){cout<<"this is USA Tank"<<endl;}
};
/
class AbstractFactory           //抽象工厂类
{public:virtual AbstractPlane *CreatePlane()=0;virtual AbstractTank *CreateTank()=0;
};class China_Factory:public AbstractFactory        //中国工厂
{public:AbstractPlane *CreatePlane(){return new J10();}AbstractTank *CreateTank(){return new China_Tank();}
};class USA_Factory:public AbstractFactory      //美国工厂
{public:AbstractPlane *CreatePlane(){return new F22();}AbstractTank *CreateTank(){return new USA_Tank();}
};///
int main()
{AbstractPlane *plane = NULL;      AbstractTank *tank = NULL;AbstractFactory *factory = NULL;    factory = new China_Factory();     //生成中国工厂 plane = factory->CreatePlane();        //生成中国的飞机 plane->operation();                    //调用中国飞机的方法 return 0;
}
/*打印结果:This is J10*/ 

C++三种工厂模式介绍及其区别相关推荐

  1. java设计模式---三种工厂模式之间的区别

    简单工厂,工厂方法,抽象工厂都属于设计模式中的创建型模式.其主要功能都是帮助我们把对象的实例化部分抽取了出来,优化了系统的架构,并且增强了系统的扩展性. 本文是本人对这三种模式学习后的一个小结以及对他 ...

  2. Factory-pattern 三种工厂模式

    解决问题 主要解决创建复杂对象的问题. 应用场景 当某一系列对象需要复杂的逻辑控制创建过程,过程创建过程比较复杂时,可以采用工厂模式. 工厂模式常见的有三种: 简单工厂模式: 又称之为静态工厂模式 工 ...

  3. 手把手教你应用三种工厂模式在SpringIOC中创建对象实例【案例详解】

    目录 一.工厂模式介绍 二.通过静态工厂方法创建Bean实例 三.通过实例工厂方法创建Bean实例 四.通过自定义的factoryBean来创建bean对象 Hello,你好呀,我是灰小猿!一个超会写 ...

  4. java 三种工厂模式

    java 三种工厂模式 一.简单工厂模式 一个栗子:  我喜欢吃面条,抽象一个面条基类,(接口也可以),这是产品的抽象类. public abstract class INoodles {/*** 描 ...

  5. 三种工厂模式的分析以及C++实现

    三种工厂模式的分析以及C++实现 简单工厂模式 简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看 ...

  6. STM32三种BOOT模式介绍

    一.三种BOOT模式介绍 所谓启动,一般来说就是指我们下好程序后,重启芯片时,SYSCLK的第4个上升沿,BOOT引脚的值将被锁存.用户可以通过设置BOOT1和BOOT0引脚的状态,来选择在复位后的启 ...

  7. Windows 记事本的 ANSI、Unicode、UTF-8 这三种编码模式有什么区别?(好)

    修改 Windows 记事本的 ANSI.Unicode.UTF-8 这三种编码模式有什么区别?修改 Windows 的记事本默认存储文本文档编码是 ANSI,想问一下为了最大跨平台兼容性,应该采用哪 ...

  8. 什么java工厂模式_java的三种工厂模式是什么?

    java的三种工厂模式:1.简单工厂模式,提供一个创建对象实例的功能,而无须关心其具体实现:2.工厂方法模式:3.抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,无须指定它们具体的类. 一. ...

  9. JAVA设计模式之工厂模式(三种工厂模式)

    1.工厂模式可以分为三类: 简单工厂模式(Simple Factory) 工厂方法模式(Factory Method) 抽象工厂模式(Abstract Factory) 简单工厂其实不是一个标准的的设 ...

最新文章

  1. main_loop()函数解析(1)
  2. 是不是用博客园编辑器插入修改图片好困难?怀念Word吧,看看用Word2010发博客教程吧~...
  3. springboot python 开发效率比较-2018年Java开发值得学习的10大技术
  4. MyBatis复习(十):注解开发
  5. 物理学与计算机相关参考文献,物理学专业论文参考文献
  6. .net session 有效时间_【面试题】|干货!.NET C# 简答题Part 07
  7. 创建FTP和Web虚拟目录的方法!
  8. 为label或者textView添加placeHolder
  9. numpy的结构数组和内存布局
  10. c#遍历匹配串口(向每个串口发数据,根据返回数据确定是否为所需串口)
  11. kindle oasis2 firmware bug汇总
  12. android PDFview加载PDFPDF加水印
  13. ubuntu查看电脑配置信息
  14. Unirech腾讯云代充-云服务器登陆及远程连接常见问题
  15. Could not autowire. No beans of 'StudentService' type found
  16. selectpicker 清空选项_boostrap selectpicker 用法
  17. 谷歌学术国内镜像网址收集-查文献
  18. 微博插件-微博图片全显示(页面样式本人优化版)
  19. Markdown 更改字体颜色
  20. css实现自定义鼠标样式

热门文章

  1. 《JSDOM编程艺术》笔记
  2. 使用高德地图展示点位和信息窗体展示数据及播放视频
  3. Win11隐藏输入法状态栏方法
  4. 【语音处理】用Matlab实现语音变速变调
  5. linux下 mount IMG文件提示“您必须指定文件系统类型”
  6. Charles手机抓包之下载、安装、配置、介绍
  7. object_funs.py
  8. 事件相机(Event-based camera)模拟器ESIM配置及使用指南
  9. linux驱动 usb转串口ch344 改变读取缓冲区大小
  10. 滨江世贸机器人编程教育_机器人少儿编程课到底要不要学,送给正在迷茫的家长们...