简单工厂模式的优点在于工厂类中包含了必要的逻辑判断,根据客户端的选择动态的实例化相关类,对于客客户端来说是去除了对产品的依赖。但是就是因为这样,每次添加一个新的选择,就要修改工厂类中的switch逻辑分支,这显然违背了开放-封闭原则;


工厂方法模式:
定义一个用于创建对象的接口,让子类决定实例化哪个类,工厂方法使一个类的实例化延迟到其子类。

工厂方法实现时,客户端需要决定实例化哪一个工厂来实现运算类,选择判断的问题依然存在,也就是说,工厂方法把简单工厂的内部逻辑判断移到了客户端进行,如果想要加功能。则是由更改工厂类转变为了更改客户端。


下面引入两个示例来介绍这个模式方法:

1 用工厂方法模式实现计算器功能:

#include <iostream>
using namespace std;
//抽象产品类
class operation
{protected:double _num_A;double _num_B;
public:double get_A(){return _num_A;}double get_B(){return _num_B;}void set_A(double num){_num_A=num;}void set_B(double num){_num_B=num;}//基类中将操作实现方法设置为虚函数virtual double getResult()=0;virtual ~operation()//当子类含有动态分配的内存时,需要把基类的析构函数声明为虚函数。//                                     此处可不用声明为虚函数。因为子类中没有动态分配的内存。此处写出知识为了举例{cout<<"base destruction"<<endl;}
};//具体产品类
//实现子类继承父类的具体实现
//实现加法功能
class operationAdd:public operation   //加法类继承自operation
{double getResult(){return _num_A+_num_B;}//构造之后进行析构 防止内存泄漏~operationAdd(){cout<<"ADD destruction"<<endl;}
};//实现减法功能
class operationSub:public operation
{double getResult(){return _num_A-_num_B;}
}; //实现乘法功能
class operationMul:public operation
{double getResult(){return _num_A*_num_B;}
};//实现除法功能
class operationdiv:public operation
{double getResult(){return _num_A/_num_B;}
};//工厂方法类
class factory//先构建一个工厂接口
{public:virtual operation* createOperation()=0;  //纯虚函数
};class addFactory:public factory
{public:operation* createOperation(){return new operationAdd();}
};class subFactory:public factory
{public:operation* createOperation(){return new operationSub();}
};class mulFactory:public factory
{public:operation* createOperation(){return new operationMul();}
};class divFactory:public factory
{public:operation* createOperation(){return new operationdiv();}
};//主界面函数体
int main()
{factory* operfactory=new addFactory();operation* add=operfactory->createOperation();add->set_A(1);add->set_B(1);cout<<add->getResult();return 0;
}
在这里插入代码片

2 工厂方法模式实现雷锋功能:

#include <iostream>
#include <string>
using namespace std;class leifeng
{public:void saodi(){cout<<"扫地 ";}void maifan(){cout<<"买饭 ";}
};class daxuesheng:public leifeng
{};class shehuizhiyuanzhe:public leifeng
{};//雷锋工厂实现
class leifengfactory
{public:virtual leifeng* CreateLeiFeng()=0;
};
//大学生工厂实现
class daxueshengFactory:public leifengfactory
{public:leifeng* CreateLeiFeng(){cout<<"大学生雷锋";return new daxuesheng;}
};class shehuizhiyuanzheFactory:public leifengfactory
{public:leifeng* CreateLeiFeng(){return new shehuizhiyuanzhe;}
};int main(){leifengfactory* lff=new daxueshengFactory;//父类指针指向子类对象 返回一个子类new出来的对象leifeng* xiaoli=lff->CreateLeiFeng();//创建雷锋类对象接收雷锋工厂对象调用子类函数的结果xiaoli->saodi();//实现雷锋对象的具体功能return 0;
}
在这里插入代码片

抽象工厂模式

提供一个创建一系列相关或相互依赖对象的接口,而不需指定他们具体的类;


抽象工厂模式的优缺点

好处便是易于交换产品系列,有与具体工厂类,在一个应用中只需要初始化的时候出现一次,这就使得改变一个应用的具体工厂变得非常容易,他只需要改变具体工厂即可使用不同的产品配置。
它让具体的创建实例过程与客户端分离,客户端是通过他们的抽象接口曹忠实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。


引入一个抽象工厂模式的示例:

#include <iostream>
#include <string>using namespace std;
//抽象工厂实现数据库访问。有两个数据库 sqlUser accessUser,每个数据库有两个表项sqldepartment  accessdepartment
class IUser
{public:virtual void setuser()=0;//设置用户virtual void getuser()=0;//获取用户
};class sqlUser:public IUser
{public:virtual void setuser(){cout<<"在SQL Server中给User增加一条记录"<<endl;}virtual void getuser(){cout<<"在SQL Server中根据ID得到User一条记录"<<endl;}
};class AccessUser:public IUser
{public:virtual void setuser(){cout<<"在Acess Server中给User增加一条记录"<<endl;}virtual void getuser(){cout<<"在Acess Server中根据ID得到User一条记录"<<endl;}
};class IDepartment
{public:virtual void getDepartment()=0;virtual void setDepartment()=0;
};class SqlDepartment:public IDepartment
{public:void getDepartment(){cout<<"在Sql Server中根据ID得到Department一条记录"<<endl;}void setDepartment(){cout<<"在Sql Server中给Department增加一条记录"<<endl;}
};class AccessDepartment:public IDepartment
{public:void getDepartment(){cout<<"在Acess Server中根据ID得到Department一条记录"<<endl;}void setDepartment(){cout<<"在Acess Server中给Department增加一条记录"<<endl;}
};class IFactory
{public:virtual IUser *createUser()=0;virtual IDepartment *createDepartment()=0;
};class SqlFactory:public IFactory
{public:IUser *createUser() {return new sqlUser();}IDepartment *createDepartment() {return new SqlDepartment();}
};class AccessFactory:public IFactory
{public:IUser *createUser(){return new AccessUser();}IDepartment *createDepartment() {return new AccessDepartment();}
};int main()
{IFactory* sql=new SqlFactory;IUser * user=sql->createUser();IDepartment* department=sql->createDepartment();user->setuser();user->getuser();department->setDepartment();department->getDepartment();return 0;}
在这里插入代码片

用简单工厂模式重写上面例子:

#include <iostream>
#include <string>using namespace std;
//抽象工厂实现//用户父类IUer  它有俩子类 即对应两个数据库
class IUser
{public:virtual void setuser()=0;virtual void getuser()=0;
};//用户子类sqlUser
class sqlUser:public IUser
{public:virtual void setuser(){cout<<"在SQL Server中给User增加一条记录"<<endl;}virtual void getuser(){cout<<"在SQL Server中根据ID得到User一条记录"<<endl;}
};
//子类用户AccessUser
class AccessUser:public IUser
{public:virtual void setuser(){cout<<"在Acess Server中给User增加一条记录"<<endl;}virtual void getuser(){cout<<"在Acess Server中根据ID得到User一条记录"<<endl;}
};//表项父类
class IDepartment
{public:virtual void getDepartment()=0;virtual void setDepartment()=0;
};//表项子类SqlDepartment
class SqlDepartment:public IDepartment
{public:void getDepartment(){cout<<"在Sql Server中根据ID得到Department一条记录"<<endl;}void setDepartment(){cout<<"在Sql Server中给Department增加一条记录"<<endl;}
};//表项子类 AccessDepartment
class AccessDepartment:public IDepartment
{public:void getDepartment(){cout<<"在Acess Server中根据ID得到Department一条记录"<<endl;}void setDepartment(){cout<<"在Acess Server中给Department增加一条记录"<<endl;}
};//获取数据
class Accessdata
{public:static string db;static IUser* createUser(){if(db=="sql")return new sqlUser;else if(db=="access")return new AccessUser;}static IDepartment* createDepartment(){if(db=="sql")return new SqlDepartment;else if(db=="access")return new AccessDepartment;}
};string Accessdata::db="sql"; //作用域int main()
{Accessdata DB;IUser * user=DB.createUser(); //获取数据库IDepartment* department=DB.createDepartment();//获取表项user->setuser();user->getuser();department->setDepartment();department->getDepartment();return 0;}
在这里插入代码片

设计模式之 工厂方法模式&&抽象工厂模式相关推荐

  1. 设计模式:工厂方法与抽象工厂模式

    说明:这篇blog写的很好,有助于理解工厂方法与抽象工厂模式的联系与区别. 原文链接:http://blog.csdn.net/yzxz/article/details/4601152 抽象工厂模式与 ...

  2. 设计模式-工厂模式 Factory Pattern(简单工厂、工厂方法、抽象工厂)

    工厂模式 Factory Pattern(简单工厂.工厂方法.抽象工厂) 工厂模式-创建型模式-提供了创建对象的最佳方式. 在工厂模式中,创建对象时不会对客户端暴露创建逻辑,并且是通过一个共同的接口来 ...

  3. 23招做项目——工厂模式:工厂方法和抽象工厂

    在网上的大多数资料里面,将工厂模式分为:简单工厂.工厂方法.抽象工厂,他们之间的联系(以电子厂为例)如下: 那么该文章首先讲解工厂模式是什么,为什么需要工厂模式,最后再对三种模式进行示例.该文章是23 ...

  4. 工厂模式(简单工厂,工厂方法,抽象工厂)

    工厂顾名思义就是创建产品,工厂分为三种:简单工厂,工厂方法,抽象工厂.该模式用于封装和管理对象的创建,是一种创建型模式. 1)简单工厂 该模式通过向工厂传递类型来指定要创建的对象 提供一个方法,根据类 ...

  5. 设计模式:简单工厂、工厂方法、抽象工厂之小结与区别

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

  6. 【设计模式实战】简单工厂、工厂方法、抽象工厂:原理篇

    小明开发的应用,经常要从XML或者Asset中读取省市区数据. 小明是这样写的: public abstract class IOHandler {/*** 添加*/public abstract v ...

  7. Android工厂设计模式(简单工厂,工厂方法,抽象工厂,BitmapFactory简单工厂分析,Retrofit抽象工厂分析)

    文章目录 创建型设计模式(简单工厂,工厂方法,抽象工厂) 一.简单工厂模式 引出简单工厂模式 二.工厂方法模式 三.抽象工厂模式 Android源码中用到的工厂模式举例 一.BitmapFactory ...

  8. 设计模式——简单工厂、工厂方法和抽象工厂的区别与联系

    前言 创建型模式中,常用的有工厂方法模式和抽象工厂模式,平时实践还包括简单工厂模式,虽然简单工厂模式不在23种设计模式中. 为了区分以上几种设计模式的差别,通过以下几个例子介绍这几种模式的使用场景以及 ...

  9. java 抽象工厂工厂_Java设计模式之简单工厂、工厂方法和抽象工厂

    学习Java的同学注意了!!! 学习过程中遇到什么问题或者想获取学习资源的话,欢迎加入Java学习交流群,群号码:456544752我们一起学Java! 在前面的学习中(参见前面的博客),我们学到了很 ...

  10. 每周一个设计模式之工厂方法与抽象工厂

    工厂方法模式与抽象工厂模式,两个模式比较相似,把任何一个独立出来,好像都不太好,所以把它们放到一起来理解会更好.不管是工厂方法还是抽象工厂,都有三个要素,那就是Client,Factory,Produ ...

最新文章

  1. 2030全球新出行产业报告:2.2万亿美元蛋糕将这样分
  2. WEB应用程序逻辑架构
  3. 5kyu Square sums (simple)
  4. python多重循环导致内存不足_Python多重处理拒绝循环
  5. C++ | 内联函数 inline
  6. debian命令乱码_Debian 9.5 解决中文显示乱码
  7. 【SpringMVC】SpringMVC和Spring集成
  8. 绑定多个下拉框数据(关系式)
  9. 实战HTML:模仿百度地图制作项目首页
  10. Atitit 加强学生就业的规划与艾提拉的治学理念 目录 1. 思路的转换 1 1.1. 发展内需为主模型 vs 外贸模式 1 1.2. 批发模式vs 零售模式vs 1 1.3. 天堂模式vs地狱模
  11. 2013搜狐移动互联战略
  12. HTML5查看CAD图纸,看cad图纸软件(DwgSee)怎么打印Cad图纸?
  13. 【平面设计基础】01:抠图—薄、透、露的朦胧美
  14. 山寨游戏之超级奥巴马(SUPER OBAMA WORLD)
  15. 黑客攻防从入门到精通 1-6章
  16. Google广告数据分析与优化总结
  17. React Native可视化开发工具
  18. html标签中写onclick,HTML a 标签添加 onclick()事件的几种方式
  19. 算法珠玑算法总结(转)
  20. 总结中间方攻击和CA认证中心

热门文章

  1. CC2541 SDA SCL 用作普通IO口
  2. 第3章 SQL 习题 - 3.4
  3. 安卓开发:经期助手App
  4. three.js 加载gltf模型的简化demo
  5. 生成对抗网络(GAN,Generative Adversarial Network)介绍
  6. C语言实现头插法建立单链表
  7. 软件安装与下载总结(三)--xmind下载安装
  8. C++常量指针与指针常量的区别
  9. Altium AD20设置过孔盖油,默认规则盖油,无网络普通过孔盖油
  10. 计算机电缆说明,计算机电缆型号名称说明