1.意圖
用原型實例指定創(chuàng)建對象的種類,并且通過拷貝這些原型創(chuàng)建新的對象冲粤。
2 動機
你可以通過定制一個通過的圖形編輯器框架和增加一些表示音符、休止符和五線譜的新對象來構造一個樂譜編輯器砸紊。這個編輯器框架可能有一個工具選擇板用于將這些音樂對象加到樂譜中其做。這個選擇板可能還包括選擇、移動和其他操縱音樂對象的工具凌唬。用戶可以點擊音符并使用它將四分音符加到樂譜中并齐。或者它們可以使用移動工具在五線譜上下移動一個音符客税,從而改變它的音調况褪。
我們假定該框架為音符和五線譜這樣的圖形構件提供了一個抽象的Graphics類。此外更耻,為定義選擇板中的那些工具测垛,還提供了抽象類Tool。該框架還創(chuàng)建圖形對象實例并將它們加入到文檔中的工具預定義了一個GraphicTool子類秧均。
但GraphicTool給框架設計者帶來一個問題食侮,音符和五線譜的類特定于我們的應用号涯,而GraphicTool類卻屬于框架。GraphicTool不知道如何創(chuàng)建我們的音樂類的實例锯七,并將它們添加到樂譜中链快。我們可以為每一個音樂對象的類別上有所不同。我們知道對象復合是比創(chuàng)建子類更靈活的一種選擇起胰,問題是久又,該框架怎么樣用它來參數(shù)化GraphicTool的實例巫延,而這些實例是由Graphic類所支持創(chuàng)建的效五。
解決辦法是讓GraphicTool通過拷貝或者克隆Graphic子類的一個實例來創(chuàng)建新的Graphic,我們稱這個實例為一個原型炉峰。GraphicTool將它應該克隆和添加到文檔中的原型作為參數(shù)畏妖。如果所有Graphic子類都支持一個Clone操作,那么GraphicTool可以克隆所有種類的Graphic疼阔,如下圖所示:
因此在我們的音樂編輯器中戒劫,用于創(chuàng)建音樂對象的每一種工具都是一個不同原型進行初始化的GraphicTool實例,通過Clone一個音樂對象的原型并將這個Clone添加到樂譜中婆廊,每一個GraphicTool實例都會產生一個音樂對象迅细。
我們甚至可以進一步使用Prototype模式來減少類的數(shù)目。我們使用不同的類來表示全音符和半音符淘邻,但可能不需要這么做茵典。它們可以是使用不同位圖和時延初始化的相同的類的實例。一個創(chuàng)建全音符的工具就是這樣的GraphicTool宾舅,它的原型是一個被初始化成全音符的MusicalNote统阿。這可以極大的減少系統(tǒng)種類的數(shù)目,同時也更易于在音樂編輯器中增加新的樂符筹我。
3 適用性
當一個系統(tǒng)應該獨立于它的產品創(chuàng)建扶平、構成和表示時,要使用Prototype模式
- 當要實例化的類是在運行時刻指定時蔬蕊,例如通過動態(tài)加載
- 為了避免創(chuàng)建一個與產品層次平行的工廠類層次時
- 當一個類的實例只能有幾個不同狀態(tài)組合中的一種時结澄,建立相應數(shù)目的原型并克隆它可能比每次用合適的狀態(tài)手工實例化該類更方便一些。
4 結構
5 參與者
- Prototype(Graphic)——聲明一個克隆自身的接口
- ConcretePrototype(Staff岸夯、WholeNote概而、HalfNote)——實現(xiàn)一個克隆自身的操作
- Client(GraphicTool)——讓一個原型克隆自身從而創(chuàng)建一個新的對象
6 協(xié)作
客戶請求一個原型克隆自身
7 效果
- 1.運行時刻增加和刪除產品;
- 2.改變值以指定新對象囱修;
- 3.改變結構以指定新對象赎瑰;
- 4.減少子類的構造;
- 5.用類動態(tài)配置應用破镰;
8 實現(xiàn)
當實現(xiàn)原型時餐曼,要考慮下面一些問題
- 1 使用一個原型管理器:當一個系統(tǒng)中原型數(shù)目不固定時(也就是說压储,它們可以動態(tài)創(chuàng)建和銷毀),要保持一個可用原型的注冊表源譬;
- 2 實現(xiàn)克隆操作Prototype模式最困難的部分在于正確實現(xiàn) Clone操作集惋。當對象結構包含循環(huán)引用時,這尤為棘手踩娘。
- 3 初始化克隆對象