原型模式

原型模式

用原型實例指定創建對象的種類,並且通過拷貝這些原型創建新的對象。

基本介紹

  • 中文名:原型模式
  • 外文名Prototype
  • 問題:結構複雜的對象”的創建工作
  • 實現clone()方法來實現對象的克隆
  • 模式Prototype
定義,解決問題,如何使用,

定義

原型模式是一種創建型設計模式,Prototype模式允許一個對象再創建另外一個可定製的對象,根本無需知道任何如何創建的細節,工作原理是:通過將一個原型對象傳給那個要發動創建的對象,這個要發動創建的對象通過請求原型對象拷貝它們自己來實施創建。

解決問題

它主要面對的問題是:“某些結構複雜的對象”的創建工作;由於需求的變化,這些對象經常面臨著劇烈的變化,但是他們卻擁有比較穩定一致的接口。

如何使用

因為Java中的提供clone()方法來實現對象的克隆,所以Prototype模式實現一下子變得很簡單。
以勺子為例:
public abstract class AbstractSpoon implements Cloneable{String spoonName;public void setSpoonName(String spoonName) {this.spoonName = spoonName;}public String getSpoonName() {return this.spoonName;}public Object clone(){Object object = null;try {object = super.clone();} catch (CloneNotSupportedException exception) {System.err.println("AbstractSpoon is not Cloneable");}return object;}}有兩個具體實現(ConcretePrototype):public class SoupSpoon extends AbstractSpoon{public SoupSpoon(){setSpoonName("Soup Spoon");}}
調用Prototype模式很簡單:
AbstractSpoon spoon = new SoupSpoon();AbstractSpoon spoon = new SaladSpoon();
當然也可以結合工廠模式來創建AbstractSpoon實例。
Java中Prototype模式變成clone()方法的使用,由於Java的純潔的面向對象特性,使得在Java中使用設計模式變得很自然,兩者已經幾乎是渾然一體了。這反映在很多模式上,如Iterator遍歷模式。
帶Prototype Manager的原型模式:客戶(Client)角色:客戶端類向原型管理器提出創建對象的請求。
抽象原型(Prototype)角色:這是一個抽象角色,通常由一個C#接口或抽象類實現。此角色給出所有的具體原型類所需的接口。在C#中,抽象原型角色通常實現了ICloneable接口。
具體原型(Concrete Prototype)角色:被複製的對象。此角色需要實現抽象的原型角色所要求的接口。
原型管理器(Prototype Manager)角色:創建具體原型類的對象,並記錄每一個被創建的對象。
代碼實現如下:
/ CplusplusPrototype.cpp : Defines the entry point for the console application.//#include "stdafx.h"#include<iostream>#include<vector>#include<assert.h>usingnamespace std;//父類class Resume{protected:char *name;public:Resume() {}virtual ~Resume() {}virtual Resume* Clone() { return NULL; }virtualvoid Set(char *n) {}virtualvoid Show() {}};class ResumeA : public Resume{public:ResumeA(constchar *str); //構造函式ResumeA(const ResumeA &r); //拷貝構造函式~ResumeA(); //析構函式ResumeA* Clone(); //克隆,關鍵所在void Show(); //顯示內容};ResumeA::ResumeA(constchar *str){if(str == NULL) {name = newchar[1];name[0] = '\0';}else {name = newchar[strlen(str)+1];strcpy(name, str);}}ResumeA::~ResumeA() { delete [] name;}ResumeA::ResumeA(const ResumeA &r) {name = newchar[strlen(r.name)+1];strcpy(name, r.name);}ResumeA* ResumeA::Clone() {returnnew ResumeA(*this);}void ResumeA::Show() {cout<<"ResumeA name : "<<name<<endl;}class ResumeB : public Resume{public:ResumeB(constchar *str); //構造函式ResumeB(const ResumeB &r); //拷貝構造函式~ResumeB(); //析構函式ResumeB* Clone(); //克隆,關鍵所在void Show(); //顯示內容};ResumeB::ResumeB(constchar *str){if(str == NULL) {name = newchar[1];name[0] = '\0';}else {name = newchar[strlen(str)+1];strcpy(name, str);}}ResumeB::~ResumeB() { delete [] name;}ResumeB::ResumeB(const ResumeB &r) {name = newchar[strlen(r.name)+1];strcpy(name, r.name);}ResumeB* ResumeB::Clone() {returnnew ResumeB(*this);}void ResumeB::Show() {cout<<"ResumeB name : "<<name<<endl;}class ResumeManager{private:vector<Resume *> mResume;public:ResumeManager(){}void add(Resume * resume){mResume.push_back(resume);}Resume * get(int index) const{assert(index>=0 && index<mResume.size());return mResume[index];}};int _tmain(int argc, _TCHAR* argv[]){ResumeManager *manager = new ResumeManager();Resume *r1 = new ResumeA("A");Resume *r2 = new ResumeB("B");manager->add(r1);manager->add(r2);manager->get(0)->Show();manager->get(1)->Show();Resume *r3 = manager->get(0)->Clone();Resume *r4 = manager->get(1)->Clone();//刪除r1,r2delete r1; delete r2;r1 = r2 = NULL;//深拷貝所以對r3,r4無影響r3->Show(); r4->Show();delete r3; delete r4;r3 = r4 = NULL;return 0;}

相關詞條

熱門詞條

聯絡我們