Prototype"原型模式" 隶属于 “对象创建模式”,目的是为了绕开new产生的具体对象所导致的依赖关系。
1. Motivation
1.1 情形分析
在软件系统中,经常面临着“某些结构复杂对象的”创建工作,由于需求的变化,这些对象经常面临着复杂的变化,但是他们有着比较稳定一致的接口。
与工厂模式不同之处在于:Prototype模式有着稳定一致的接口。
1.2 提出问题
如何应对这些变化? 如何从客户端程序隔离出这些“易变对象”?从而使“依赖这些易变对象的客户端”,不随着需求的变化而变化?
2. Show Me The Code
- 将工厂模式的代码
SplitterFactory
类拿过来,然后将两个类合二为一,再做一点小小的修改—clone():
//抽象类
class ISplitter{
public:
virtual void split()=0;
virtual ISplitter* clone()=0; //通过克隆自己来创建对象
virtual ~ISplitter(){}
};
工厂模式传送门:Factory Method工厂模式
从分离到合并
- 将具体类也进行修改:
//具体类
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);
}
};
与原先类对比,改动了哪里?
//Prototype模式
class BinarySplitter : public ISplitter{
public:
virtual ISplitter* clone(){
//调用拷贝构造函数
return new BinarySplitter(*this);
}
};
//Factory模式
//具体工厂
class BinarySplitterFactory: public SplitterFactory{
public:
virtual ISplitter* CreateSplitter(){
//应该返回一个指针类型对象,所以用new。
return new BinarySplitter();
}
};
注意这里的return new BinarySplitter(*this);
我拷贝我自己,加*解引用。
在c++中提供了一个很强大的功能—拷贝构造函数,使用new可以进行深拷贝,即完全拷贝,没有依赖堆栈的关系。
- MainForm文件怎么改动?
class MainForm : public Form
{
ISplitter* prototype;//原型对象
public:
MainForm(ISplitter* prototype){
this->prototype=prototype;
}
void Button1_Click(){
ISplitter * splitter=
prototype->clone(); //克隆原型
splitter->split();
//不能直接使用:prototype->split();
}
};
注释处:为什么不能直接使用
prototype->split();
原因是原型对象不是供使用的,它是用来拷贝的,不能直接对它进行使用。
3. 定义
使用原型实例来创建对象的种类,然后通过拷贝这些原型来创建新的对象。 —《设计模式》GoF
这里的克隆是指深克隆。如new BinarySplitter(*this);
4. 类图
结束语:这个模式用的不是很常见,权当了解一下。