在软件系统种,经常面临着“某些结构复杂的对象”的创建工作,由于需求的变化,这些对象经常面临着剧烈的变化,但是他们却拥有比较稳定一致的接口。
如何应对这种变化?如何向“客户程序(使用这些对象的程序)”隔离出这些“易变对象”,从而使得“以来这些易变对象的客户程序”不随需求改变而改变?
原型系统在笔者看来是个有点搞的设计模式,他把工厂和product合并了,创建的时候通过拷贝构造函数的形式来进行。挺简单一设计模式。看看代码能看懂。
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ISplitter* clone()=0; //通过克隆自己来创建对象
virtual ~ISplitter(){}
};
//具体类
class BinarySplitter : public ISplitter{
public:
virtual ISplitter* clone(){
return new BinarySplitter(*this);
}
};
class TxtSplitter: public ISplitter{
public:
virtual ISplitter* clone(){
return new TxtSplitter(*this);
}
};
class PictureSplitter: public ISplitter{
public:
virtual ISplitter* clone(){
return new PictureSplitter(*this);
}
};
class VideoSplitter: public ISplitter{
public:
virtual ISplitter* clone(){
return new VideoSplitter(*this);
}
};
class MainForm : public Form
{
ISplitter* prototype;//原型对象
public:
MainForm(ISplitter* prototype){
this->prototype=prototype;
}
void Button1_Click(){
ISplitter * splitter=
prototype->clone(); //克隆原型
splitter->split();
}
};
MainForm中的原型对象不是给你用的,当你要用的时候把它当一个工厂,拷贝他就行了,注意得是深拷贝,自己重写一下拷贝构造函数,默认拷贝用的是浅拷贝。当然,这个分场景的哈,如果你需要通过原型对象控制所有克隆对象,即通过对原型对象的修改扩散至其他对象,就用浅拷贝。
原型模式其实也能一定程度解决工厂模式要为每一个类建工厂的行为。比如造车,宝马三系,宝马五系,宝马七系等等等。那就是要为每一个系列造一个工厂咯。但是其实这三种车型有共同的地方,我们都使他们继承自一种宝马基础款,创建宝马基础款的原型对象。在调用clone函数的时候,传一些不同车型的一些小特质,比如发动机啥的,达到一个原型能创建多种对象的效果。
说到这感觉和抽象工厂目的一致,但是这俩方向不同,抽象工厂是要创建一系列有关联的对象,原型模式还是只创建一个,只是对象之间相似度比较高。
笔者认为原型模式还挺厉害的,但是好像原型模式不太使用的原因就是需要对之前的类中的源代码进行修改吧,违反了开闭原则,所以不太受待见。(猜测猜测哈,如果不对希望大佬们指正)