[设计模式] 设计模式课程(七)--工厂模式

描述

  • 属于“对象创建模式”
  • 避免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 };
View Code

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 };
View Code
  • 子类实例化接口
  • 用多态的方式实例化子类
  • 实现类中存在对具体子类的依赖

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 };
View Code

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 };
View Code

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 };
View Code
  • 具体类和实现类都依赖于抽象,解除了编译时依赖
  • MainForm构造方法中从外界传递具体的Splitter,通过虚函数实现了运行时依赖
原文地址:https://www.cnblogs.com/cxc1357/p/12302185.html