设计模式之四-Factory模式
简单工厂模式
简单工厂模式是工厂模式中最简单的一种,他可以用比较简单的方式隐藏创建对象的细节,一般只需要告诉工厂类所需要的类型,工厂类就会返回需要的产品类,但客户端看到的只是产品的抽象对象,无需关心到底是返回了哪个子类。客户端唯一需要知道的具体子类就是工厂子类。除了这点,基本是达到了依赖倒转原则的要求。
假如,我们不用工厂类,只用AbstractProduct和它的子类,那客户端每次使用不同的子类的时候都需要知道到底是用哪一个子类,当类比较少的时候还没什么问题,但是当类比较多的时候,管理起来就非常的麻烦了,就必须要做大量的替换,一个不小心就会发生错误。
而使用了工厂类之后,就不会有这样的问题,不管里面多少个类,我只需要知道类型号即可。不过,这里还有一个疑问,那就是如果我每次用工厂类创建的类型都不相同,这样修改起来的时候还是会出现问题,还是需要大量的替换。所以简单工厂模式一般应该于程序中大部分地方都只使用其中一种产品,工厂类也不用频繁创建产品类的情况。这样修改的时候只需要修改有限的几个地方即可。
客户只需要知道SimpleFactory就可以了,使用的时候也是使用的AbstractFactory,这样客户端只在第一次创建工厂的时候是知道具体的细节的,其他时候它都只知道AbstractFactory,这样就完美的达到了依赖倒转的原则。
常用的场景
例如部署多种数据库的情况,可能在不同的地方要使用不同的数据库,此时只需要在配置文件中设定数据库的类型,每次再根据类型生成实例,这样,不管下面的数据库类型怎么变化,在客户端看来都是只有一个AbstractProduct,使用的时候根本无需修改代码。提供的类型也可以用比较便于识别的字符串,这样不用记很长的类名,还可以保存为配置文件。
这样,每次只需要修改配置文件和添加新的产品子类即可。
所以简单工厂模式一般应用于多种同类型类的情况,将这些类隐藏起来,再提供统一的接口,便于维护和修改。
优点
1.隐藏了对象创建的细节,将产品的实例化推迟到子类中实现。
2.客户端基本不用关心使用的是哪个产品,只需要知道用哪个工厂就行了,提供的类型也可以用比较便于识别的字符串。
3.方便添加新的产品子类,每次只需要修改工厂类传递的类型值就行了。
4.遵循了依赖倒转原则。
缺点
1.要求产品子类的类型差不多,使用的方法名都相同,如果类比较多,而所有的类又必须要添加一种方法,则会是非常麻烦的事情。或者是一种类另一种类有几种方法不相同,客户端无法知道是哪一个产品子类,也就无法调用这几个不相同的方法。
2.每添加一个产品子类,都必须在工厂类中添加一个判断分支,这违背了开放-封闭原则。
C++实现代码
#ifndef _ABSTRACTPRODUCT_H_ #define _ABSTRACTPRODUCT_H_#include <stdio.h>class AbstractProduct{public:AbstractProduct();virtual ~AbstractProduct();public:virtual void operation() = 0; };class ProductA:public AbstractProduct{public:ProductA();virtual ~ProductA();public:void operation(); };class ProductB:public AbstractProduct{public:ProductB();~ProductB();public:void operation(); };#endifAbstractProduct.h
#include "AbstractProduct.h"AbstractProduct::AbstractProduct(){ }AbstractProduct::~AbstractProduct(){ }ProductA::ProductA(){ }ProductA::~ProductA(){ }void ProductA::operation(){fprintf(stderr,"productA operation!\n"); }ProductB::ProductB(){ }ProductB::~ProductB(){ }void ProductB::operation(){fprintf(stderr,"productB operation!\n"); }AbstractProduct.cpp
#ifndef _SIMPLEFACTORY_H_ #define _SIMPLEFACTROY_H_#include <stdio.h> #include "AbstractProduct.h"class AbstractFactory{public:AbstractFactory();virtual ~AbstractFactory();public:virtual AbstractProduct* createProduct(int type) = 0; };class SimpleFactory:public AbstractFactory{public:SimpleFactory();~SimpleFactory();public:AbstractProduct* createProduct(int type); };#endifSimpleFactory.h
#include "SimpleFactory.h"AbstractFactory::AbstractFactory(){ }AbstractFactory::~AbstractFactory(){ }SimpleFactory::SimpleFactory(){ }SimpleFactory::~SimpleFactory(){ }AbstractProduct* SimpleFactory::createProduct(int type){AbstractProduct* temp = NULL;switch(type){case 1:temp = new ProductA();break;case 2:temp = new ProductB();break;default:break;}return temp; }SimpleFactory.cpp
#include "SimpleFactory.h"int main(){AbstractFactory* factory = new SimpleFactory();AbstractProduct* product = factory->createProduct(1);product->operation();delete product;product = NULL;product = factory->createProduct(2);product->operation();delete product;product = NULL;return 0; }client.cpp
工厂模式
工厂模式基本与简单工厂模式差不多,上面也说了,每次添加一个产品子类都必须在工厂类中添加一个判断分支,这样违背了开放-封闭原则,因此,工厂模式就是为了解决这个问题而产生的。
既然每次都要判断,那我就把这些判断都生成一个工厂子类,这样,每次添加产品子类的时候,只需再添加一个工厂子类就可以了。这样就完美的遵循了开放-封闭原则。但这其实也有问题,如果产品数量足够多,要维护的量就会增加,好在一般工厂子类只用来生成产品类,只要产品子类的名称不发生变化,那么基本工厂子类就不需要修改,每次只需要修改产品子类就可以了。
同样工厂模式一般应该于程序中大部分地方都只使用其中一种产品,工厂类也不用频繁创建产品类的情况。这样修改的时候只需要修改有限的几个地方即可。
常用的场景
基本与简单工厂模式一致,只不过是改进了简单工厂模式中的开放-封闭原则的缺陷,使得模式更具有弹性。将实例化的过程推迟到子类中,由子类来决定实例化哪个。
优点
基本与简单工厂模式一致,多的一点优点就是遵循了开放-封闭原则,使得模式的灵活性更强。
缺点
与简单工厂模式差不多。
C++实现代码
#ifndef _ABSTRACTPRODUCT_H_ #define _ABSTRACTPRODUCT_H_#include <stdio.h>class AbstractProduct{public:AbstractProduct();virtual ~AbstractProduct();public:virtual void operation() = 0; };class ProductA:public AbstractProduct{public:ProductA();virtual ~ProductA();public:void operation(); };class ProductB:public AbstractProduct{public:ProductB();~ProductB();public:void operation(); };#endifAbstractProduct.h
#include "AbstractProduct.h"AbstractProduct::AbstractProduct(){ }AbstractProduct::~AbstractProduct(){ }ProductA::ProductA(){ }ProductA::~ProductA(){ }void ProductA::operation(){fprintf(stderr,"productA operation!\n"); }ProductB::ProductB(){ }ProductB::~ProductB(){ }void ProductB::operation(){fprintf(stderr,"productB operation!\n"); }AbstractProduct.cpp
#ifndef _SIMPLEFACTORY_H_ #define _SIMPLEFACTROY_H_#include <stdio.h> #include "AbstractProduct.h"class AbstractFactory{public:AbstractFactory();virtual ~AbstractFactory();public:virtual AbstractProduct* createProduct() = 0; };class FactoryA:public AbstractFactory{public:FactoryA();~FactoryA();public:AbstractProduct* createProduct(); };class FactoryB:public AbstractFactory{public:FactoryB();~FactoryB();public:AbstractProduct* createProduct(); }; #endifAbstractFactory.h
#include "AbstractFactory.h"AbstractFactory::AbstractFactory(){ }AbstractFactory::~AbstractFactory(){ }FactoryA::FactoryA(){ }FactoryA::~FactoryA(){ }AbstractProduct* FactoryA::createProduct(){AbstractProduct* temp = NULL;temp = new ProductA();return temp; }FactoryB::FactoryB(){ }FactoryB::~FactoryB(){ }AbstractProduct* FactoryB::createProduct(){AbstractProduct* temp = NULL;temp = new ProductB();return temp; }AbstractFactory.cpp
#include "AbstractFactory.h"int main(){AbstractFactory* factory = new FactoryA();AbstractProduct* product = factory->createProduct();product->operation();delete product;product = NULL;delete factory;factory = NULL;factory = new FactoryB();product = factory->createProduct();product->operation();delete product;product = NULL;delete factory;factory = NULL;return 0; }client.cpp
抽象工厂模式
抽象工厂模式就变得比工厂模式更为复杂,就像上面提到的缺点一样,工厂模式和简单工厂模式要求产品子类必须要是同一类型的,拥有共同的方法,这就限制了产品子类的扩展。于是为了更加方便的扩展,抽象工厂模式就将同一类的产品子类归为一类,让他们继承同一个抽象子类,我们可以把他们一起视作一组,然后好几组产品构成一族。
此时,客户端要使用时必须知道是哪一个工厂并且是哪一组的产品抽象类。每一个工厂子类负责产生一族产品,而子类的一种方法产生一种类型的产品。在客户端看来只有AbstractProductA和AbstractProductB两种产品,使用的时候也是直接使用这两种产品。而通过工厂来识别是属于哪一族产品。
产品ProductA_1和ProductB_1构成一族产品,对应于有Factory1来创建,也就是说Factory1总是创建的ProductA_1和ProductB_1的产品,在客户端看来只需要知道是哪一类工厂和产品组就可以了。一般来说, ProductA_1和ProductB_1都是适应同一种环境的,所以他们会被归为一族。
常用的场景
例如Linux和windows两种操作系统下,有2个挂件A和B,他们在Linux和Windows下面的实现方式不同,Factory1负责产生能在Linux下运行的挂件A和B,Factory2负责产生能在Windows下运行的挂件A和B,这样如果系统环境发生变化了,我们只需要修改工厂就行了。
优点
1.封装了产品的创建,使得不需要知道具体是哪种产品,只需要知道是哪个工厂就行了。
2.可以支持不同类型的产品,使得模式灵活性更强。
3.可以非常方便的使用一族中间的不同类型的产品。
缺点
1.结构太过臃肿,如果产品类型比较多,或者产品族类比较多,就会非常难于管理。
2.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
C++实现代码
#ifndef _ABSTRACTPRODUCTA_H_ #define _ABSTRACTPRODUCTA_H_#include <stdio.h>class AbstractProductA{public:AbstractProductA();virtual ~AbstractProductA();public:virtual void operationA() = 0; };class ProductA_1:public AbstractProductA{public:ProductA_1();virtual ~ProductA_1();public:void operationA(); };class ProductA_2:public AbstractProductA{public:ProductA_2();~ProductA_2();public:void operationA(); };#endifAbstractProductA.h
#include "AbstractProductA.h"AbstractProductA::AbstractProductA(){ }AbstractProductA::~AbstractProductA(){ }ProductA_1::ProductA_1(){ }ProductA_1::~ProductA_1(){ }void ProductA_1::operationA(){fprintf(stderr,"productA_1 operation!\n"); }ProductA_2::ProductA_2(){ }ProductA_2::~ProductA_2(){ }void ProductA_2::operationA(){fprintf(stderr,"productA_2 operation!\n"); }AbstractProductA.cpp
#ifndef _ABSTRACTPRODUCTB_H_ #define _ABSTRACTPRODUCTB_H_#include <stdio.h>class AbstractProductB{public:AbstractProductB();virtual ~AbstractProductB();public:virtual void operationB() = 0; };class ProductB_1:public AbstractProductB{public:ProductB_1();virtual ~ProductB_1();public:void operationB(); };class ProductB_2:public AbstractProductB{public:ProductB_2();~ProductB_2();public:void operationB(); };#endifAbstractProductB.h
#include "AbstractProductB.h"AbstractProductB::AbstractProductB(){ }AbstractProductB::~AbstractProductB(){ }ProductB_1::ProductB_1(){ }ProductB_1::~ProductB_1(){ }void ProductB_1::operationB(){fprintf(stderr,"productB_1 operation!\n"); }ProductB_2::ProductB_2(){ }ProductB_2::~ProductB_2(){ }void ProductB_2::operationB(){fprintf(stderr,"productB_2 operation!\n"); }AbstractProductB.cpp
#ifndef _SIMPLEFACTORY_H_ #define _SIMPLEFACTROY_H_#include <stdio.h> #include "AbstractProductA.h" #include "AbstractProductB.h"class AbstractFactory{public:AbstractFactory();virtual ~AbstractFactory();public:virtual AbstractProductA* createProductA() = 0; virtual AbstractProductB* createProductB() = 0; };class Factory1:public AbstractFactory{public:Factory1();~Factory1();public:AbstractProductA* createProductA();AbstractProductB* createProductB(); };class Factory2:public AbstractFactory{public:Factory2();~Factory2();public:AbstractProductA* createProductA();AbstractProductB* createProductB(); }; #endifAbstractFactory.h
#include "AbstractFactory.h"AbstractFactory::AbstractFactory(){ }AbstractFactory::~AbstractFactory(){ }Factory1::Factory1(){ }Factory1::~Factory1(){ }AbstractProductA* Factory1::createProductA(){AbstractProductA* temp = NULL;temp = new ProductA_1();return temp; }AbstractProductB* Factory1::createProductB(){AbstractProductB* temp = NULL;temp = new ProductB_1();return temp; }Factory2::Factory2(){ }Factory2::~Factory2(){ }AbstractProductA* Factory2::createProductA(){AbstractProductA* temp = NULL;temp = new ProductA_2();return temp; }AbstractProductB* Factory2::createProductB(){AbstractProductB* temp = NULL;temp = new ProductB_2();return temp; }AbstractFactory.cpp
#include "AbstractFactory.h"int main(){AbstractFactory* factory = new Factory1();AbstractProductA* productA = factory->createProductA();AbstractProductB* productB = factory->createProductB();productA->operationA();productB->operationB();delete factory;factory = NULL;delete productA;productA = NULL;delete productB;productB = NULL;factory = new Factory2();productA = factory->createProductA();productB = factory->createProductB();productA->operationA();productB->operationB();delete factory;factory = NULL;delete productA;productA = NULL;delete productB;productB = NULL;return 0; }client.cpp
转载自http://www.cnblogs.com/cxjchen/p/3143633.html
转载于:https://www.cnblogs.com/wanzaiyimeng/p/6831168.html
设计模式之四-Factory模式相关推荐
- C#设计模式之四建造者模式(Builder Pattern)【创建型】
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...
- D5:C#设计模式之四建造者模式(Builder Pattern)【创建型】
一.引言 今天我们要讲讲Builder模式,也就是建造者模式,当然也有叫生成器模式的,英文名称是Builder Pattern.在现实生活中,我们经常会遇到一些构成比较复杂的物品,比如:电脑,它就是一 ...
- C++设计模式之四 模板模式
<TemplateMethod1.h> #include <iostream> #include <string> using namespace std; cla ...
- 图解设计模式-Abstract Factory模式
抽象工厂的工作是将"抽象零件"组装成"抽象产品". 我们不关心零件的具体实现,而是只关心接口API.我们仅适用该接口API将零件组装成为产品. 角色: Abst ...
- 设计模式之四(抽象工厂模式第三回合)
原文:设计模式之四(抽象工厂模式第三回合) 前言 抽象工厂模式:提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类. 抽象工厂模式最大的好处便是易于交换产品系列,由于具体工厂类,例如I ...
- (原创)无废话C#设计模式之四:Factory Method
无废话C#设计模式之四:Factory Method <a href='http://xgb.xgb.cc'>a</a> <a href='http:// ...
- IOS设计模式之四(备忘录模式,命令模式)
本文原文请见:http://www.raywenderlich.com/46988/ios-design-patterns. 由 @krq_tiger(http://weibo.com/xmuzyq) ...
- Java设计模式(1)工厂模式(Factory模式)
工厂模式定义:提供创建对象的接口. 为何使用工厂模式 工厂模式是我们最常用的模式了,著名的Jive论坛,就大量使用了工厂模式,工厂模式在Java程序系统可以说是随处可见. 为什么工厂模式是如此常用?因 ...
- 设计模式-Builder和Factory模式区别
Builder和Factory模式区别 Builder模式结构: Factory模式一进一出,Builder模式是分步流水线作业. 当你需要做一系列有序的工作或者按照一定的逻辑来完成创建一个对象时 B ...
最新文章
- 初探WCF 如何在配置文件中指定Address?
- mysql 5.7配置多线程复制,MySQL5.7复制功能实战,基于事务的复制,多源复制和多线程复制配置...
- Eclipse 的一些调试技巧
- 【解决办法】read_csv()第一列作为index
- Java集合框架:Collections工具类
- SK-Learn使用NMF(非负矩阵分解)和LDA(隐含狄利克雷分布)进行话题抽取
- HDU1598【最小生成树拓展】
- 畅游互联的API接口如何对接到自己的网站上?
- linspace函数matlab_Matlab入门2-莫比乌斯环
- python有什么用-Python到底有什么用?为什么那么多人都在学Python?
- 定时任务发展史(二)
- ddwrt开启USB硬盘
- pfn_to_page 函数
- 重磅预告!企业上云的正确姿势
- VS Code 取色器 插件 颜色选取
- JUnit 4 超详细教程(一)
- 如何下载矢量电子地图
- Arduino +合宙ESP32C3 +1.8/1.44 寸TFT液晶屏驱动显示
- 英语语法总结_02 名词词组与代名词
- 【快进来,这不是毒鸡汤,只是有毒而已】
热门文章
- python数据处理实例-python数据分析实例(1)
- python哪一版好用-学习 Python 用哪本书好?
- python读取excelsheet-一文看懂用Python读取Excel数据
- python输出数据到excel-python如何导出数据到excel文件
- python好吗-自学python好吗?跟培训比那个好?
- python经典100例答案pdf-Python3基础训练经典100题(带答案)下载
- python官网没有中文-python 检查是否为中文字符串的方法
- python基础知识面试题-Python 基础面试题总结
- python数字类型-Python Number(数字)
- 从小白到精通python要多久-零基础如何学Python?小白学Python需要多久?