工厂模式属于对象创建模式.
通过 "对象创建"模式绕开new,避免对象创建(new)导致的紧耦合,从而支持对象创建的稳定.它是接口抽象之后的第一步工作.
典型的对象创建模式:
- Factory Method
- Abstract Factory
- Prototype
- Builder
本文介绍工厂模式.
实例
考虑一个窗口程序,在按键按下的时候执行文件分割的操作.
class FileSplitter{
public:
void Split(){
//do split
}
};
class MainForm: public Form{
public:
void OnButtonClick(){
FileSplitter* file_splitter=new FileSplitter();//依赖具体类
file_splitter->Split();
}
};
考虑到FileSplitter
是比较容易改变的,可以定义一个文件分类的接口类,然后通过继承实现对其他类型文件的分割,MainForm
类的指针也变为接口类的指针.
各种FileSplitter
类
class FileSplitterInterface{
public:
virtual void Split()=0;
virtual ~FileSplitterInterface(){ }
};
class TxtSplitter:public FileSplitterInterface{
public:
virtual void Split(){
//do tex split
}
};
class BinarySplitter:public FileSplitterInterface{
public:
virtual void Split(){
//do binary split
}
};
class PictureSplitter:public FileSplitterInterface{
//do pic split
virtual void Split(){}
};
class VideoSpitter:public FileSplitterInterface{
//do video split
virtual void Split(){ }
};
MainForm::OnButtonClick
函数中依赖具体的FileSplitter
实现,这个依赖是不好的,我们希望把这个依赖干掉,应该依赖的抽象,而不是实现细节,我们希望MainForm
类仅依赖抽象.
首先我们考虑如下的设计方式,利用一个类的成员函数来创建对象.
class SplitterFactory{
public:
FileSplitterInterface* CreatFileSpilitter(){
return new TxtSplitter();//具体的实现细节
}
};
class MainForm: public Form{
public:
void OnButtonClick(){
SplitterFactory spliter_factory;
FileSplitterInterface* file_splitter=spliter_factory.CreatFileSpilitter();
file_splitter->Split();
}
};
这样的处理MainForm
还是依赖于具体的实现细节,但是给了我们优化的方向,要想让MainForm
只依赖抽象,我们需要把CreatFileSpilitter()
变成虚函数,SplitterFactory
变成抽象基类.
class MainForm: public Form{
private:
SplitterFactory* spliter_factory_;
public:
MainForm( SplitterFactory* spliter_factory):spliter_factory_(spliter_factory){
}
void OnButtonClick(){
FileSplitterInterface* file_splitter=spliter_factory_->CreatFileSpilitter();
file_splitter->Split();
}
};
//工厂
class SplitterFactory{
public:
virtual FileSplitterInterface* CreatFileSpilitter()=0;
virtual ~SplitterFactory(){}
};
//具体工厂
class TxtSplitterFactory:public SplitterFactory{
public:
virtual FileSplitterInterface* CreatFileSpilitter(){
return new TxtSplitter();
}
};
class BinarySplitterFactory:public SplitterFactory{
public:
virtual FileSplitterInterface* CreatFileSpilitter(){
return new BinarySplitter();
}
};
class PictureSplitterFactory:public SplitterFactory{
public:
virtual FileSplitterInterface* CreatFileSpilitter(){
return new PictureSplitter();
}
};
class VideoSpitterFactory:public SplitterFactory{
public:
virtual FileSplitterInterface* CreatFileSpilitter(){
return new VideoSpitter();
}
};
**工厂模式,**定义一个用于创建对象的接口,让子类决定实例化哪一个类.Factory Method 使得一个类的实例化得到了延迟到子类.这么做的目的是解耦,实现的手段是虚函数.
类图
要点总结
- Factory Method 模式用于隔离类对象的使用者和具体类型之间的耦合关系.面对一个经常变化的类型,紧耦合关系(new)会导致软件的脆弱
- Factory Method 通过面向对象的手法,将创建具体对象的工作延迟到子类,从而实现一种扩展而非更改的策略,较好的解决了这种耦合关系.