设计模式之抽象工厂模式
抽象工厂模式,提供一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。其UML图如下:
结合上图我们来理解一下抽象工厂模式的定义。提供一个创建一些列相关或相互依赖对象的接口,而无需指定它们具体的类。在上图中一系列相互依赖或相关的对象可以理解为ProductA,ProductB,也可以有ProductC、ProductD等,这些是一系列类,要创建这一系列对象。而这一系列对象有不同的类型,比如Product1,和Product2,同样的可以是Product3等。在抽象工厂模式中创建这一系列对象是由相关的工厂负责的。比如 ConcreteFactory1负责创建ProductA1、ProductB1、ProductC1等,同样的ConcreteFactory2负责创建ProductA2、ProductB2、ProductC2等。这就是定义中说的创建一系列对象的接口,而这借口就是工厂。至于无需指定它们具体的类就很明显了,因为创建相关系列的对象的时候只需用指定相关的工厂就可以了,客户端根本不需要知道具体要创建的类是什么。
举个例子吧,就拿键盘和鼠标来说吧,键盘和鼠标就是一些列的类。而键盘鼠标又有微软的和联想的区别。所有有了微软的工厂和联想的工厂。键盘和鼠标具体的创建由工厂来负责,而具体创建微软的还是联想的则由客户端来指定,而客户端根本不用知道鼠标和键盘这些类。此例的示例代码如下:
1 // AbstractFactoryModel.h文件 2 #pragma once 3 #include <iostream> 4 5 // 键盘 6 class KeyBoard 7 { 8 public: 9 virtual void show() = 0; 10 }; 11 // 微软的键盘 12 class KeyBoardMicro : public KeyBoard 13 { 14 public: 15 void show() 16 { 17 std::cout << "微软的键盘" << std::endl; 18 } 19 }; 20 // 联想的键盘 21 class KeyBoardLenovo : public KeyBoard 22 { 23 public: 24 void show() 25 { 26 std::cout << "联想的键盘" << std::endl; 27 } 28 }; 29 // 鼠标 30 class Mouse 31 { 32 public: 33 virtual void show() = 0; 34 }; 35 36 class MouseMicro : public Mouse 37 { 38 public: 39 void show() 40 { 41 std::cout << "微软的鼠标" << std::endl; 42 } 43 }; 44 45 class MouseLenovo : public Mouse 46 { 47 public: 48 void show() 49 { 50 std::cout << "联想的鼠标" << std::endl; 51 } 52 }; 53 // 工厂 54 class Factory 55 { 56 public: 57 virtual KeyBoard * createKeyBoard() = 0; 58 virtual Mouse * createMouse() = 0; 59 }; 60 // 微软的工厂 61 class FactoryMicro : public Factory 62 { 63 public: 64 KeyBoard * createKeyBoard() 65 { 66 return new KeyBoardMicro(); 67 } 68 Mouse * createMouse() 69 { 70 return new MouseMicro(); 71 } 72 }; 73 // 联想的工厂 74 class FactoryLenovo : public Factory 75 { 76 public: 77 KeyBoard * createKeyBoard() 78 { 79 return new KeyBoardLenovo(); 80 } 81 Mouse * createMouse() 82 { 83 return new MouseLenovo(); 84 } 85 };
测试代码如下:
1 #include <iostream> 2 #include "AbstractFactoryModel.h" 3 4 int main() 5 { 6 using namespace std; 7 // 抽象工厂模式 8 Factory * p = new FactoryMicro(); 9 KeyBoard * pKeyBoard = p->createKeyBoard(); 10 Mouse * pMouse = p->createMouse(); 11 pKeyBoard->show(); 12 pMouse->show(); 13 delete pMouse; 14 delete pKeyBoard; 15 delete p; 16 17 p = new FactoryLenovo(); 18 pKeyBoard = p->createKeyBoard(); 19 pMouse = p->createMouse(); 20 pKeyBoard->show(); 21 pMouse->show(); 22 delete pMouse; 23 delete pKeyBoard; 24 delete p; 25 26 getchar(); 27 return 0; 28 }
测试结果如下图:
抽象工厂模式和工厂方法模式很相似。最大的区别就是抽象工厂模式不止一个产品簇,并且每个工厂都不止生产一种产品。比如在工厂方法模式中,不同的工厂可以生产不同的产品。比如键盘、鼠标。分别由键盘工厂和鼠标工厂,但是智能生产一种键盘和鼠标。但是在抽象工厂模式中,每个工厂可以生产键盘和鼠标。还可以生产不同牌子的键盘和鼠标。说到这里,其实抽象工厂模式可以和简单工厂模式结合起来,来创建不同的工厂。
抽象工厂模式最大的好处便是易于交换产品系列,只要改变创建的工厂对象就可以实现产品系列的更换。还有一个优点是它让具体的创建实例的过程于客户端分离,客户端是通过它们抽象接口操纵实例,产品的具体类名也被具体工厂的实现分离,不会出现在客户代码中。最大的缺点是如果像添加产品则非常麻烦需要修改很多类。