为什么需要工厂模式?
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种“封装机制”来避免客户程序和这种“具体对象创建工作”的紧耦合?
举例说明
//文件分割器
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{
};
class MainForm : public Form
{
TextBox* txtFilePath;
TextBox* txtFileNumber;
ProgressBar* progressBar;
public:
void Button1_Click(){
/***************************变化****************************/
ISplitter * splitter=
new BinarySplitter();//依赖具体类,不符合依赖倒置原则
/****************************变化**************************/
splitter->split();//不能动态调用不同具体类的split函数
}
};
如上述代码所示,客户端程序依赖于具体的对象(编译时依赖),不符合依赖倒置原则。每次创建对象的变化都要修改代码,不符合开闭原则。
因此,我们需要一种设计模式来消除对象使用者和具体类型之间的紧耦合关系。
什么是工厂模式?
定义一个用于创建对象的接口(工厂基类),让子类(具体工厂类)决定实例化哪一个类。Factory Method使得一个类的实例化延迟(目的:解耦, 手段:虚函数)到子类。
类图
类图中,
Product:是产品基类;ConcreteProduct:是具体产品类;Creator:工厂基类;Concretecreator:是具体工厂类。
Concretecreator类依赖ConcreteProduct类。
示例代码
//产品基类
class ISplitter{
public:
virtual void split()=0;
virtual ~ISplitter(){}
};
//工厂基类
class SplitterFactory{
public:
virtual ISplitter* CreateSplitter()=0;
virtual ~SplitterFactory(){}
};
//具体产品类
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();
}
};
//客户程序
class MainForm : public Form
{
SplitterFactory* factory;//工厂基类指针
public:
MainForm(SplitterFactory* factory){//将具体工厂对象以参数形式传入。
this->factory=factory;
}
void Button1_Click(){
/*************************稳定****************************/
ISplitter * splitter=
factory->CreateSplitter(); //【多态new】 根据所传入具体工厂类的不同,动态创建不同的具体功能类【具体工厂中:return new XXXX】
/***************************稳定***************************/
splitter->split();
}
};
虚函数:将变化延迟到运行时;将变化关在笼子里,并不是变化消失了
工厂模式特点
通过“对象创建” 模式绕开new,来避免对象创建(new)过程中所导致的紧耦合(依赖具体类),从而支持对象创建的稳定。它是接口抽象之后的第一步工作。
Factory Method模式用于隔离类对象的使用者和具体类型之间的耦合关系。面对一个经常变化的具体类型,紧耦合关系(new)会导致软件的脆弱。
Factory Method模式通过面向对象的手法(多态),将所要创建的具体对象工作延迟到子类,从而实现一种扩展(而非更改)的策略,较好地解决了这种紧耦合关系。
Factory Method模式解决“单个对象”的需求变化。缺点在于要求创建方法/参数相同。