工厂方法模式

  • 通过“对象创建”模式绕开new,来避免对象创建(new) 过程中所导致的紧耦合(依赖工具类),从而支持对象创建的稳定。他是接口抽象之后的第一步工作
  • 典型模式
    • Factory Method
    • Abstract Factory
    • Prototype
    • Builder
  • 动机
    • 在软件系统中,经常面临着创建对象的工作,由于需求的变化,需要创建的对象的基本类型经常变化
    • 如何应对这种变化,如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合
  • 缺点
    • 要求所创建方法/参数相同

      sample

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      class FileSplitter{
      public:
      void split(){

      }
      }

      class MainForm:public Form{
      TextBox* textFilePath;
      TextBox* textFileNumber;
      ProgressBar* progressBar;

      public:
      void Button1_Click(){
      string filePath = txtFilePath;
      int number = atoi(textFilePath->getText());
      FileSplitter* splitter= new FileSplitter(filePath,number);
      splitter->split();
      }
      }

      问题与改进

  • 设定成具体的类(FileSplitter),失去了可扩展性
    • 解决方案,面向抽象编程
  • 依赖倒置
    • 依赖抽象,不依赖细节

      sample

      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      class ISplitter{
      public:
      virtual void split()=0;
      virtual ~ISplitter(){}
      }

      class TxtSplitter:public ISplitter{

      };

      class PrictureSplitter:public ISplitter{

      };

      class VideoSplitter:public ISplitter{

      }

      class MainForm:public Form{
      TextBox* textFilePath;
      TextBox* textFileNumber;
      ProgressBar* progressBar;

      public:
      void Button1_Click(){
      string filePath = txtFilePath;
      int number = atoi(textFilePath->getText());
      ISplitter* splitter= new FileSplitter(filePath,number); // FileSplitter 细节依赖
      splitter->split();
      }
      }

工厂设计模式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
}
class BinarySplitter:public ISplitter{

};
class TxtSplitter:public ISplitter{

};

class PrictureSplitter:public ISplitter{

};

class VideoSplitter:public ISplitter{

}

class SplitterFactory{
public :
//1.0 造成 MainForm 依赖 SplitterFactory ,SplitterFactory 依赖 TxtSplitter,
// **************************************
// ISplitter* createSplitter(){
// return new TxtSplitter();
// }
//
//2.0
virtual ISplitter* createSplitter()=0;
virtual ~SplitterFactory(){}
}
//2.0
class BinarySplitterFactory:SplitterFactory{
public:
ISplitter* createSplitter(){
return new BinarySplitter();
}
};
//2.0
class vFactory:SplitterFactory{
public:
ISplitter* createSplitter(){
return new TxtSplitter();
}
};
//2.0
class PrictureSplitterFactory:SplitterFactory{
public:
ISplitter* createSplitter(){
return new PrictureSplitter();
}
};
//2.0
class VideoSplitterFactory:SplitterFactory{
public:
ISplitter* createSplitter(){
return new VideoSplitter();
}
};

//2.0
class MainForm:public Form{
SplitterFactory* factory;

public:
Mainform(SplitterFactory* factory){
this->factory = factory;
}

void Button1_Click(){
string filePath = txtFilePath;
int number = atoi(textFilePath->getText());
SplitterFactory* factory;
ISplitter* splitter= SplitterFactory->createSplitter(); // 多态 new
splitter->split();
}
}

模式定义

定义一个用于创建对象的接口,让子类决定延迟实例化那个一个类。Factor Method使得一个子类的实例化延迟 (目的:结偶,手段虚函数) 到子类

UML图示

工厂模式UML图示

要点总结

  • Factory Method 模式用于隔离类对象的使用者和具体类型之间的耦合关系,面对一个经常变化的具体类型,紧耦合关系会导致软件异常脆弱
  • Factory Mathod 模式通过面相对象的手法,将所要创建的具体工作 延迟 到子类,从而实现一种 扩展(而非更改) 的策略。较好的解决了这种紧耦合关系
  • Factory Method 模式解决”单个对象“的需求变。缺点在于要求所 创建的方法/参数相同