1.什么是原型模式?
2.為什么要使用原型模式?
如果一個對象的創建過程比較復雜時(比如需要經過一系列的計算和資源消耗),那每次創建該對象都需要消耗資源,而通過原型模式就可以復制現有的一個對象來迅速創建/克隆一個新對象,不必關心具體的創建細節,可以降低對象創建的成本。
3.原型模式的基本結構
實現原型模式需要給【原型對象】聲明一個克隆方法,執行該方法會創建一個當前類的新對象,并將原始對象中的成員變量復制到新生成的對象中,而不必實例化。并且在這個過程中只需要調用原型對象的克隆方法,而無需知道原型對象的具體類型。
原型模式包含兩個重點模塊:
- 抽象原型接口
prototype
: 聲明一個克隆自身的方法clone
- 具體原型類
ConcretePrototype
: 實現clone
方法,復制當前對象并返回一個新對象。
在客戶端代碼中,可以聲明一個具體原型類的對象,然后調用clone()
方法復制原對象生成一個新的對象。
4.原型模式的實現過程
原型模式的實現過程即上面描述模塊的實現過程:
- 創建一個抽象類或接口,聲明一個克隆方法
clone
- 實現具體原型類,重寫克隆方法(多態)
- 客戶端中實例化具體原型類的對象,并調用其克隆方法來創建新的對象。
5.C++實現原型模式
【設計模式專題之原型模式】5. 矩形原型 (kamacoder.com)https://kamacoder.com/problempage.php?pid=1083
題目描述:
公司正在開發一個圖形設計軟件,其中有一個常用的圖形元素是矩形。設計師在工作時可能需要頻繁地創建相似的矩形,而這些矩形的基本屬性是相同的(顏色、寬度、高度),為了提高設計師的工作效率,請你使用原型模式設計一個矩形對象的原型。使用該原型可以快速克隆生成新的矩形對象。
輸入描述:
首先輸入一個字符串,表示矩形的基本屬性信息,包括顏色、長度和寬度,用空格分隔,例如 "Red 10 5"。
然后輸入一個整數 N(1 ≤ N ≤ 100),表示使用原型創建的矩形數量。
輸出描述:
對于每個矩形,輸出一行字符串表示矩形的詳細信息,如 "Color: Red, Width: 10,Height: 5"。
輸入示例:
Red 10 5
3
輸出示例:
Color: Red, Width: 10, Height: 5
Color: Red, Width: 10, Height: 5
Color: Red, Width: 10, Height: 5
?代碼實現:
#include<iostream>
#include<string>
#include<vector>
using namespace std;// 定義抽象原型類
class Prototype{
public://聲明clone方法virtual Prototype* clone() const = 0;//為了方便打印信息,所以設計了這樣一個抽象函數。const表示不修改成員屬性virtual string getDetails() const = 0;//虛析構,寫成虛析構是為了防止子類創建在堆區時,父類的指針指向子類的對象,該指針無法釋放子類堆區的內存的問題virtual ~Prototype() {}};//定義矩形原型類
class RectanglePrototype : public Prototype{
//由于輸入的數據有矩形的顏色、長、寬,所以要有這些成員屬性
private:string color;int width;int heigth;public://初始化列表法實現構造函數。這里的列表一定要和private定義的順序一致RectanglePrototype(string Color, int Width, int Heigth): color(Color),width(Width),heigth(Heigth){} //具體化克隆方法Prototype* clone() const override{//因為clone方法要復制當前對象并返回一個新對象,所以這里使用了系統提供的拷貝構造函數對屬性進行值拷貝,return new RectanglePrototype(*this);}//具體化獲取細節的方法string getDetails() const override{return "Color: "+color + "," + " Width: "+ to_string(width)+"," + " Height: "+to_string(heigth);}};//客戶端代碼
int main()
{string s;int w, h, num;cin>>s>>w>>h;cin>>num;//vector<Prototype *> Rectangles;for(int i = 0; i<num; i++){// 創建原型對象并保存在數組中Prototype * rectangle = new RectanglePrototype(s,w,h);Rectangles.push_back(rectangle);}//克隆原型對象并輸出被克隆對象的信息for(const auto& rec : Rectangles){Prototype* clonedRectangle = rec->clone(); //值拷貝cout<<clonedRectangle->getDetails()<<endl;//釋放克隆對象內存delete clonedRectangle;}//釋放原型對象for(const auto& rec : Rectangles){delete rec;}return 0;
}