描述
- 属于“对象创建模式”
- 避免new过程中导致的紧耦合问题(依赖具体类),从而支持对象创建的稳定,是接口抽象后的第一步工作,也是面向接口编程的必然需求
- 定义一个用于创建对象的接口(工厂接口),再让子类(具体工厂)决定实例化哪个类
- 面向接口编程,变量声明成抽象基类
- 通过面向对象的方法,将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了紧耦合问题
- 简单工厂:需要创建多种对象时,把对象创建的代码剥离到一个类中,if-else语句判断创建哪种对象(违反开闭原则)
- 工厂:每个对象对应一个工厂类,客户端一次写死,通过多态的方式创建对象,具体类的扩展更加便捷
- 红色代表部分稳定,蓝色代表部分变化。MainForm依赖红色部分,后期蓝色部分有增加具体类的需求,不影响红色部分
- 缺点:要求创建方法 / 参数相同,不适用于有多种分类 / 二级分类对象的创建
- 多种分类:图形根据形状分为直线、矩形、椭圆;根据颜色分为红色、蓝色、绿色
- 二级分类:家电分为电视、冰箱、洗衣机,冰箱分为普通型和节能型
- 抽象工厂可解决二级分类问题(超过二级会变得非常臃肿)
场景
- 你需要一辆汽车,可以直接去工厂里提货,而不用管汽车是怎么做出来的
- Hibernate换数据库,只需要换方言和驱动即可
- 调用者想要创建一个对象,只要知道其名称即可,想要增加一个产品,只要扩展一个工厂类即可
- 日志记录器:数据可能记录到本地硬盘、系统事件、远程服务器等,用户可以选择记录日志到什么地方
- 数据库访问时,用户不知道最后采用哪种数据库,或数据库可能有变化时
- 设计一个连接服务器的矿井爱,需要三个协议,POP3,IMAP,HTTP,可以把这三个定义为产品类,共同实现一个接口
示例1
MainForm1.cpp

1 class MainForm : public Form 2 { 3 TextBox* txtFilePath; 4 TextBox* txtFileNumber; 5 ProgressBar* progressBar; 6 7 public: 8 void Button1_Click(){ 9 10 ISplitter * splitter= 11 new BinarySplitter();//依赖具体类 12 13 splitter->split(); 14 15 } 16 };
FileSplitter1.cpp

1 class ISplitter{ 2 public: 3 virtual void split()=0; 4 virtual ~ISplitter(){} 5 }; 6 7 class BinarySplitter : public ISplitter{ 8 9 }; 10 11 class TxtSplitter: public ISplitter{ 12 13 }; 14 15 class PictureSplitter: public ISplitter{ 16 17 }; 18 19 class VideoSplitter: public ISplitter{ 20 21 };
- 子类实例化接口
- 用多态的方式实例化子类
- 实现类中存在对具体子类的依赖
MainForm2.cpp

1 class MainForm : public Form 2 { 3 SplitterFactory* factory;//工厂 4 5 public: 6 7 MainForm(SplitterFactory* factory){ 8 this->factory=factory; 9 } 10 11 void Button1_Click(){ 12 13 ISplitter * splitter= 14 factory->CreateSplitter(); //多态new 15 16 splitter->split(); 17 18 } 19 };
ISplitterFactory.cpp

1 //抽象类 2 class ISplitter{ 3 public: 4 virtual void split()=0; 5 virtual ~ISplitter(){} 6 }; 7 8 //工厂基类 9 class SplitterFactory{ 10 public: 11 virtual ISplitter* CreateSplitter()=0; 12 virtual ~SplitterFactory(){} 13 };
FileSplitter2.cpp

1 //具体类 2 class BinarySplitter : public ISplitter{ 3 4 }; 5 6 class TxtSplitter: public ISplitter{ 7 8 }; 9 10 class PictureSplitter: public ISplitter{ 11 12 }; 13 14 class VideoSplitter: public ISplitter{ 15 16 }; 17 18 //具体工厂 19 class BinarySplitterFactory: public SplitterFactory{ 20 public: 21 virtual ISplitter* CreateSplitter(){ 22 return new BinarySplitter(); 23 } 24 }; 25 26 class TxtSplitterFactory: public SplitterFactory{ 27 public: 28 virtual ISplitter* CreateSplitter(){ 29 return new TxtSplitter(); 30 } 31 }; 32 33 class PictureSplitterFactory: public SplitterFactory{ 34 public: 35 virtual ISplitter* CreateSplitter(){ 36 return new PictureSplitter(); 37 } 38 }; 39 40 class VideoSplitterFactory: public SplitterFactory{ 41 public: 42 virtual ISplitter* CreateSplitter(){ 43 return new VideoSplitter(); 44 } 45 };
- 具体类和实现类都依赖于抽象,解除了编译时依赖
- MainForm构造方法中从外界传递具体的Splitter,通过虚函数实现了运行时依赖