1.工厂模式介绍
参考:
JAVA设计模式之工厂模式(简单工厂模式+工厂方法模式)
将类的实例化(具体产品的创建)延迟到工厂类的子类(具体工厂)中完成,即由子类来决定应该实例化(创建)哪一个类。
工厂模式重要的四部分:
对应UML:
两个抽象类,一个是抽象产品类Product,一个是抽象工厂类Factory,具体的产品类派生自抽象产品类,具体的工厂类派生自抽象工厂类。
2.工厂模式示例
下面的代码描述的是一个文件分割器的例子,代码并不严谨,只用于说明问题。
文件分割器可能有多种,比如二进制文件分割器、文本文件分割器、视频文件分割器等。
抽象类包含各种分割器的共有方法split()
。
工厂基类中包含生成各种分割器的共有方法CreateSplitter()
,该函数返回的是一个抽象类的指针,该指针指向具体的分割器(毕竟抽象类没办法实例化),基类指针指向派生类对象。
//抽象类
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();
}
};
每个具体的产品都有相应的工厂类,具体工厂类通过继承抽象工厂类并对CreateSplitter()进行复写实现具体产品类对象的创建。
客户端代码:
class MainForm : public Form
{
SplitterFactory* factory;//工厂
public:
MainForm(SplitterFactory* factory){
this->factory=factory;
}
void Button1_Click(){
ISplitter * splitter=
factory->CreateSplitter(); //多态new,注意这里
splitter->split();
}
};
可以看出,此时的客户端代码中全部是抽象类的东西,不包含具体实现,通过抽象类ISplitter和SplitterFactory实现了多态new,把具体实现隔离出去。
客户端代码只包含上图中红色的部分,这部分是稳定的,将上图中的蓝色部分(易变的部分,可能根据需求变化而变化,不稳定)隔离出去,蓝色部分的改动不会影响客户端代码,因为客户端代码调用蓝色部分是在运行时决定的(虚函数实现的运行时多态),编译时不会影响。
3.总结
注意上图中标记的部分:
1、面向对象的手法指的是多态;
2、延迟到子类也是多态;
3、扩展(而非更改)是说的下面这段代码:
ISplitter * splitter=
factory->CreateSplitter(); //多态new,注意这里
这段代码不会受具体产品更改的影响,运行时才会和具体产品相关,产品的扩展只需要增加相应的产品和工厂即可。