C++设计模式之——抽象工厂模式(AbstractFactoryPattern)
2016-02-22 15:14
691 查看
抽象工厂模式
工厂模式和简单工厂模式要求产品子类必须要是同一类型的,拥有共同的方法,这就限制了产品子类的扩展。于是为了更加方便的扩展,抽象工厂模式就将同一类的产品子类归为一类,让他们继承同一个抽象子类,我们可以把他们一起视作一组,然后好几组产品构成一族。此时,客户端要使用时必须知道是哪一个工厂并且是哪一组的产品抽象类。每一个工厂子类负责产生一族产品,而子类的一种方法产生一种类型的产品。在客户端看来只有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.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
实例代码
运行结果
工厂模式和简单工厂模式要求产品子类必须要是同一类型的,拥有共同的方法,这就限制了产品子类的扩展。于是为了更加方便的扩展,抽象工厂模式就将同一类的产品子类归为一类,让他们继承同一个抽象子类,我们可以把他们一起视作一组,然后好几组产品构成一族。此时,客户端要使用时必须知道是哪一个工厂并且是哪一组的产品抽象类。每一个工厂子类负责产生一族产品,而子类的一种方法产生一种类型的产品。在客户端看来只有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.每次如果添加一组产品,那么所有的工厂类都必须添加一个方法,这样违背了开放-封闭原则。所以一般适用于产品组合产品族变化不大的情况。
实例代码
//AbstractFactory.h #ifndef _ABSTRACTFACTORY_H_ #define _ABSTRACTFACTORY_H_ #include "AbstractProductA.h" #include "AbstractProductB.h" class AbstractFactory { public: virtual AbstractProductA* CreateProductA() = 0; virtual AbstractProductB* CreateProductB() = 0; }; class Factory1:public AbstractFactory { public: AbstractProductA* CreateProductA(); AbstractProductB* CreateProductB(); }; class Factory2 :public AbstractFactory { public: AbstractProductA* CreateProductA(); AbstractProductB* CreateProductB(); }; #endif
//AbstractFactory.cpp #include "stdafx.h" #include "AbstractFactory.h" #include <iostream> using std::cout; using std::endl; AbstractProductA* Factory1::CreateProductA() { return new ProductA_1; } AbstractProductB* Factory1::CreateProductB() { return new ProductB_1; } AbstractProductA* Factory2::CreateProductA() { return new ProductA_2; } AbstractProductB* Factory2::CreateProductB() { return new ProductB_2; }
//AbstractProductA.h #ifndef _ABSTRACTPRODUCTA_H_ #define _ABSTRACTPRODUCTA_H_ class AbstractProductA { public: virtual void OperationA() = 0; }; class ProductA_1 :public AbstractProductA { public: void OperationA(); }; class ProductA_2 :public AbstractProductA { public: void OperationA(); }; #endif
//AbstractProductA.cpp #include "stdafx.h" #include "AbstractProductA.h" #include <iostream> using std::cout; using std::endl; void ProductA_1::OperationA() { cout << "ProductA_1::OperationA()" << endl; } void ProductA_2::OperationA() { cout << "ProductA_2::OperationA()" << endl; }
//AbstractProductB.h #ifndef _ABSTRACTPRODUCTB_H_ #define _ABSTRACTPRODUCTB_H_ class AbstractProductB { public: virtual void OperationB() = 0; }; class ProductB_1 :public AbstractProductB { public: void OperationB(); }; class ProductB_2 :public AbstractProductB { public: void OperationB(); }; #endif
//AbstractProductB.cpp #include "stdafx.h" #include "AbstractProductB.h" #include <iostream> using std::cout; using std::endl; void ProductB_1::OperationB() { cout << "ProductB_1::OperationB()" << endl; } void ProductB_2::OperationB() { cout << "ProductB_2::OperationB()" << endl; }
运行结果
相关文章推荐
- 根据C语言改写的java实现的,判定九宫格是否合法。记录
- C语言的位运算的优势 !
- C++学习笔记:为什么不要重载逻辑与和逻辑或&& || 操作符
- 发布 Victor 串口控件 1.5.0.5 for C++ Builder 10 (CX) / XE8 / XE7 / XE6
- C++学习笔记:重载 函数调用符()
- MPEG-7描述子(3)——颜色布局描述子CLD
- C++中类型的转换
- C++中的变量初始化
- C++ 函数传参
- C++运算符重载和模板
- 算法训练 连续正整数的和
- C++编程教程_箭头(->)运算符的重载
- C++多态性
- 论C和C++中main函数的重要性
- C++学习笔记:数组的操作符重载(包括[]和=运算符)
- 【C++11新特性】 Lambda表达式
- 关于squirrel语言与C++的自动绑定问题(1)
- 【转】C/C++ struct/class/union内存对齐
- [C/C++标准库]_[0基础]_[优先队列priority_queue的使用]
- OpenJudge百炼习题解答(C++)--题4110:圣诞老人的礼物-Santa Clau’s Gifts