1. 需要解决的问题
代码1 : FileSplitter1.cpp
class ISplitter
{ //抽象基类
public:
virtual void split() = 0;
virtual ~ISplitter() {}
};
class BinarySplitter : public ISplitter
{
};
class TxtSplitter : public ISplitter
{
};
class PictureSplitter : public ISplitter
{
};
class VideoSplitter : public ISplitter
{
};
代码2: MainForm.cpp
(这个是客户端)
#include "FileSplitter1.cpp"
class MainForm : public Form
{
TextBox *txtFilePath;
TextBox *txtFileNumber;
ProgressBar *progressBar;
public:
void Button1_Click()
{
//面向接口原则
//依赖倒置原则
ISplitter *splitter =
new BinarySplitter(); //依赖具体类, 现在想要把这个依赖去除
splitter->split();
}
};
问题缘由:
在代码:
ISplitter *splitter =
new BinarySplitter(); //依赖具体类, 现在想要把这个依赖去除
中, 客户端的需要创建BinarySplitter(), 需要依赖这个类, 我们现在不想要依赖这个类.
也就是说, 当我们把左边的变成了抽象之后, 右边的我们也想变抽像.
这种是接口抽象之后的第一步工作.
具体见下图("对象创建"模式的作用):
2. 抽丝剥茧走向工厂模式
2.1 想一个方法, 不使用new来创建对象
- 直接实例化:
BinarySplitter b
, 不行, 也是依赖 ISplitter i
, 也不行- 写一个方法, 返回新的对象
2.2 写一个方法, 返回新的对象
-
新建一个工厂类, 里面有一个方法:
class SplitterFactory{ public: ISplitter* CreateSplitter(){ return new BinarySplitter(); } };
-
客户端里的代码变成:
SplitterFactory factory; ISiplitter* splitter = factory.CreateSplitter();
上面1, 2的做法其实也是一样的, 因为工厂的创建方法需要依赖BinarySplitter, 因此客户端里的创建方法也是间接需要依赖BinarySplitter的.
那我们怎么弄才能变成运行时依赖呢? 通过虚函数实现运行时绑定:
我们把代码改为:
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter() = 0;
virtual ~SplitterFactory(){}
};
//客户端:
SplitterFactory* factory;//因为是抽象的, 因此只能用指针
ISplitter* splitter = factory->CreateSplitter();
3. 最后的代码
现在的代码是: MainForm类和工厂类都很稳定, 如果需要增加其他功能, 新增工厂子类和功能类即可, 不需要修改. 符合开-闭原则
//file: main_form.cpp
#include "file_splitter.cpp"
//MainForm已经不依赖别的了: 很稳定了
//里面有m_factory和splitter, 都是抽象的
class MainForm{
SplitterFactory* m_factory;
public:
MainForm(SplitterFactory* factory): m_factory(factory){}
void execute(){
ISplitter* splitter = m_factory->CreateSplitter(); //用工厂创建分割器, 具体是什么要看传经来的factory
splitter->split(); //根据上面不同的工厂返回不同的分割器
}
};
int main(int argc, char const *argv[])
{
//我想创建一个文本分割器
TxtSplitterFactory* text_factory = new TxtSplitterFactory;
MainForm m_f(text_factory);
m_f.execute();
delete text_factory;
return 0;
}
//file: file_splitter.cpp
#include <iostream>
using namespace std;
class ISplitter
{ //抽象基类
public:
virtual void split() = 0;
virtual ~ISplitter() {}
};
class SplitterFactory
{
public:
virtual ISplitter *CreateSplitter() = 0;
virtual ~SplitterFactory() {}
};
//具体类
class BinarySplitter : public ISplitter
{
public:
void split()
{
cout << "binary" << endl;
}
};
class TxtSplitter : public ISplitter
{
public:
void split()
{
cout << "text" << endl;
}
};
//具体工厂
class BinarySplitterFactory : public SplitterFactory
{
public:
virtual ISplitter *CreateSplitter()
{
return new BinarySplitter;
}
};
class TxtSplitterFactory : public SplitterFactory
{
public:
virtual ISplitter *CreateSplitter()
{
return new TxtSplitter;
}
};