动机
在软件系统中,经常面临着创建对象的工作;由于需求的变化,需要创建的对象的具体类型经常变化。
如何应对这种变化?如何绕过常规的对象创建方法(new),提供一种封装机制来避免客户程序和这种具体对象创建工作的紧耦合?
代码示例:
MainForm方法调用Splitter将东西进行切分,有二进制文件切分、txt文件切分、图片文件切分、视频文件切分。
第一版:ISplitter * splitter= new BinarySplitter();这种写法依赖于具体类,违反依赖倒置原则(高层模块不应该依赖于低层模块,而是应该依赖于抽象。同时,抽象不应该依赖于具体实现,具体实现应该依赖于抽象。由编译时处理换成运行时处理)
// 抽象基类
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();}
};
第二版:具体调用工厂,MainForm不依赖于具体的类,而是依赖于抽象类和工厂基类。
class MainForm : public Form
{SplitterFactory* factory;//工厂public:MainForm(SplitterFactory* factory){this->factory=factory;}void Button1_Click(){ISplitter * splitter=factory->CreateSplitter(); //多态newsplitter->split();}
};
ISplitterFactory
//抽象类
class ISplitter{
public:virtual void split()=0;virtual ~ISplitter(){}
};//工厂基类
class SplitterFactory{
public:virtual ISplitter* CreateSplitter()=0; // 创建对象virtual ~SplitterFactory(){}
};
FileSplitter文件:几个具体的工厂继承自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();}
};
工厂方法定义
定义一个用于创建对象的接口,让子类决定实例化哪一个类。 Factory Method使一个类的实例化延迟到其子类。
具体到上面的代码,用于创建对象的接口SplitterFactory,让子类(BinarySplitterFactory,TxtSplitterFactory等具体工厂)决定实例化哪一个类。
在下列情况下可以使用Factory Method模式:
• 当一个类不知道它所必须创建的对象的类的时候。
• 当一个类希望由它的子类来指定它所创建的对象的时候。
• 当类将创建对象的职责委托给多个帮助子类中的某一个,并且你希望将哪一个帮助子类是代理者这一信息局部化的时候。(classes delegate responsibility to one of several helper subclasses, and you want to localize the knowledge of which helper subclass is the delegate.)