Prototype
動機
- 經常面臨這“某些結構複雜的對象”的創建工作;由於需求的變化,這些對象經常面臨着劇烈的變化,但是它們卻擁有比較穩定一致的接口。
- 如何應對這種變化?如何向“客戶程序(使用這些對象的程序)”隔離出“這些易變對象”,從而使得依賴這些”易變對象“的客戶程序不隨着需求改變而改變。
模式定義
使用原型實例指定創建對象的種類,然後通過拷貝(深拷貝)這些原型來創建新的對象。 ——《設計模式》GoF
要點總結
- 用於隔離對象的使用者和具體類型(易變類)之間的耦合關係,它同樣要求這些“易變類”擁有穩定的接口。
- 對於“如何創建易變類的實體對象“採用”原型克隆“的方法來做, 它使得我們可以非常靈活地動態創建”擁有某些穩定接口“的新對象——所需工作僅僅是註冊一個新類的對象(即原型), 然後在任何需要的地方Clone。
- 模式中的Clone方法可以利用某些框架中的序列化來實現深拷貝。(C++使用拷貝構造函數)
- 需要考慮對象很複雜的中間狀態,選用原型模式,否則工廠模式即可;(初始狀態 or 中間狀態)
Demo
Client.cpp:
class MainForm : public Form
{
ISplitter* prototype;//原型對象
public:
MainForm(ISplitter* prototype){
this->prototype=prototype;
}
void Button1_Click(){
ISplitter *splitter = //原型對象不是供使用的,需克隆一份
prototype->clone(); //克隆原型
splitter->split();
delete splitter;
}
};
Prototype.cpp:
//抽象類
//相當於將工廠模式的“抽象類”與“工廠基類”合二爲一
//即傳入的工廠類改爲接口
class ISplitter{
public:
virtual void split()=0;
virtual ISplitter* clone()=0; //通過克隆自己來創建對象
virtual ~ISplitter(){}
};
ConcretePrototype.cpp:
//具體類
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);
}
};