0%

设计模式之工厂模式

设计模式基础(6):工厂模式

包含工厂方法&抽象工厂两种模式中的C++示例代码、面向的问题、图解两种模式核心思想

工厂方法

面向的需求

在主体代码中绕开new方法创建对象,解除因为new而导致的主体代码和某一具体类的紧耦合关系。从而保证主体代码的可复用性。

示例代码

采用工厂方法解耦后创建对象的示例代码

1
2
3
4
5
6
7
8
9
10
11
12
13
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};

//工厂基类
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=0;
virtual ~SplitterFactory(){}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
class MainForm : public Form
{
SplitterFactory* factory;//工厂

public:

MainForm(SplitterFactory* factory){
this->factory=factory;
}

void Button1_Click(){


ISplitter * splitter=
factory->CreateSplitter(); //多态new

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
//具体类
class BinarySplitter : public ISplitter{
};
class TxtSplitter: public ISplitter{
};
class PictureSplitter: public ISplitter{
};
class VideoSplitter: public ISplitter{
};

//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new BinarySplitter();
}
};

class TxtSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new TxtSplitter();
}
};

class PictureSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new PictureSplitter();
}
};

class VideoSplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
return new VideoSplitter();
}
};

代码思想分析

  • 类图关系

    常规new的思想图解

    原始类图

    工厂方法下的思想图解

    工厂方法类图

  • 核心思想

    将具体类型的确定,延迟到运行时确定。具体的类型由外部信息确定,确保自身框架的稳定性。

    定义一个用于创建对象的接口,让子类决定实例化哪一个类。(目的:解耦,手段:虚函数)。

    结构图

关键点

  • 面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。而工厂方法将使用者(mainform)和具体类型隔离开,达到松耦合关系。
  • 利用面向对象的手法,将所要创建的具体对象延迟到子类,更有利于扩展功能。

抽象工厂

面向的需求

当多种类之间具有关联性,需要限制相互关系时。采用工厂方法进行生产时不能保证相互联系,可以考虑抽象工厂。

示例代码

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
//数据库访问有关的基类
class IDBConnection{
};
class IDBCommand{
};
class IDataReader{
};

class IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;
};

//支持SQL Server
class SqlConnection: public IDBConnection{
};
class SqlCommand: public IDBCommand{
};
class SqlDataReader: public IDataReader{
};

class SqlDBFactory:public IDBFactory{
public:
virtual IDBConnection* CreateDBConnection()=0;
virtual IDBCommand* CreateDBCommand()=0;
virtual IDataReader* CreateDataReader()=0;

};

//支持Oracle
class OracleConnection: public IDBConnection{

};

class OracleCommand: public IDBCommand{

};

class OracleDataReader: public IDataReader{

};

class EmployeeDAO{
IDBFactory* dbFactory;

public:
vector<EmployeeDO> GetEmployees(){
IDBConnection* connection =
dbFactory->CreateDBConnection();
connection->ConnectionString("...");

IDBCommand* command =
dbFactory->CreateDBCommand();
command->CommandText("...");
command->SetConnection(connection); //关联性

IDBDataReader* reader = command->ExecuteReader(); //关联性
while (reader->Read()){

}

}
};

代码分析&思想

  • 类图分析

    抽象工厂类图

  • 一个工厂中产生一系列产品,这一系列产品(类)具有相关性。

    抽象工厂结构图

关键点

内含高内聚的设计思路。工厂中既要兼顾生成,又要兼顾品类的关联性。