C++設計模式之原型模式_C 語言

來源:互聯網
上載者:User

什麼是原型模式?

在GOF的《設計模式:可複用物件導向軟體的基礎》中是這樣說的:用原型執行個體指定建立對象的種類,並且通過拷貝這些原型建立新的對象。這這個定義中,最重要的一個詞是“拷貝”,也就是口頭上的複製,而這個拷貝,也就是原型模式的精髓所在。

舉一個最簡單的例子來說明原型模式:記得上小學的時候,老師把需要做的課外習題寫到黑板上,而下面的我們都要把這些題抄寫到自己的本子上,回家做好,第二天交上來,也就是每道題,全班50個人,每個人都要抄寫一遍。按照現在的時間理論來說,就是浪費了50個人的時間。但是,那個時候條件限制,老師也是不得已而為之。現在好了,老師做一份電子版的習題,列印一份,然後拿著這份列印的原版,就可以複製出50份。

結合原型模式的概念進行分析,老師列印出來的那一份,就是“原型”,而複製出來的那50份,就是使用的“拷貝”。而原型模式就是這麼簡單的一個道理,通過現有的東西,再複製出一個來。

為什麼要使用原型模式?

原型模式和建造者模式、Factory 方法模式一樣,都屬於建立型模式的一種。簡單的來說,我們使用原型模式,就是為了建立對象。但是,在以下情境下,使用原型模式是最好的選擇:

1.當我們的物件類型不是開始就能確定的,而這個類型是在運行期確定的話,那麼我們通過這個類型的對象複製出一個新的對象比較容易一些;

2.有的時候,我們需要一個對象在某個狀態下的副本,此時,我們使用原型模式是最好的選擇;例如:一個對象,經過一段處理之後,其內部的狀態發生了變化;這個時候,我們需要一個這個狀態的副本,如果直接new一個新的對象的話,但是它的狀態是不對的,此時,可以使用原型模式,將原來的對象拷貝一個出來,這個對象就和之前的對象是完全一致的了;

3.當我們處理一些比較簡單的對象時,並且對象之間的區別很小,可能就幾個屬性不同而已,那麼就可以使用原型模式來完成,省去了建立對象時的麻煩了;

4.有的時候,建立對象時,建構函式的參數很多,而自己又不完全的知道每個參數的意義,就可以使用原型模式來建立一個新的對象,不必去理會建立的過程,讓建立過程見鬼去吧。
所以,在上述的的情況下,在設計的時候,適當的考慮一下原型模式,減少對應的工作量,減少程式的複雜度,提高效率。

用UML類圖表示原型模式

由於複製需要一個原型,而上面的類圖中Prototype就這個原型,Prototype定義了複製自身的Clone介面,由衍生類別進行實現,而實現原型模式的重點就在於這個Clone介面的實現。ConcretePrototype1類和ConcretePrototype2類繼承自Prototype類,並實現Clone介面,實現複製自身的操作;同時,在ConcretePrototype1類和ConcretePrototype2類中需要重寫預設的複製建構函式,供Clone函數調用,Clone就是通過在內部調用重寫的複製建構函式實現的。在後續的編碼過程中,如果某個類需要實現Clone功能,就只需要繼承Prototype類,然後重寫自己的預設複製建構函式就好了。好比在C#中就提供了ICloneable介面,當某個類需要實現原型模式時,只需要實現這個介面的道理是一樣的。

代碼實現

複製代碼 代碼如下:

/*
** FileName     : PrototypePatternDemo
** Author       : Jelly Young
** Date         : 2013/11/25
** Description  : More information, please go to http://www.jb51.net
*/
 
#include <iostream>
using namespace std;
 
//介面
class Prototype
{
public :
    Prototype(){}
    virtual ~Prototype(){}
 
    virtual Prototype * Clone() = 0;
};
 
//實現
class ConcretePrototype : public Prototype
{
public :
    ConcretePrototype():m_counter(0){}
    virtual ~ConcretePrototype(){}
 
    //拷貝建構函式
    ConcretePrototype( const ConcretePrototype & rhs)
    {
        m_counter = rhs .m_counter;
    }
 
    //複製自身
    virtual ConcretePrototype * Clone()
    {
        //調用拷貝建構函式
        return new ConcretePrototype (*this );
    }
 
private :
    int m_counter;
};
 
int main(int argc , char **argv)
{
    //產生對像
    ConcretePrototype * conProA = new ConcretePrototype ();
 
    //複製自身
    ConcretePrototype * conProB = conProA->Clone();
 
    delete conProA;
    conProA= NULL ;
 
    delete conProB;
    conProB= NULL ;
 
    return 0;
}

上述代碼實現了一個最簡單的原型模式,但是已經將原型模式的基本實現原理展現出來了。而有的時候,當調用Clone獲得了一個複製的對象以後,需要改變對象的狀態,此時就可能需要在ConcretePrototype類中添加一個Initialize操作,專門用於初始化複製對象。由於在Clone的內部調用的是複製建構函式,而此處又涉及到深複製和淺複製的問題。所以,在實際操作的過程中,這些問題,都需要進行仔細的考慮。

與其它建立型模式的比較

Factory 方法模式、抽象原廠模式、建造者模式和原型模式都是建立型模式。Factory 方法模式適用於生產較複雜,一個工廠生產單一的一種產品的時候;抽象原廠模式適用於一個工廠生產多個相互依賴的產品;建造者模式著重於複雜物件的一步一步建立,組裝產品的過程,並在建立的過程中,可以控制每一個簡單對象的建立;原型模式則更強調的是從自身複製自己,建立要給和自己一模一樣的對象。

總結

原型模式作為建立型模式中最特殊的一個模式,具體的建立過程,是由對象本身提供,這樣我們在很多的情境下可以很方便的快速的構建新的對象。但是,原型模式的最大缺點是繼承原型的子類都要實現Clone操作,這個是很困難的。例如,當所考慮的類已經存在時就難以新增Clone操作。當內部包括一些不支援拷貝或者有循環參考的對象時,實現複製可能也會很困難。說以說,每一種設計模式都有它的優點和缺點,在設計的時候,我們需要進行權衡各方面的因素,揚長避短。

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.