3.4 PROTOTYPE(原型) — 物件建立型模式

weixin_33924312發表於2017-12-30
1.意圖

用原型例項指定建立物件的種類,並且通過拷貝這些原型建立新的物件。

2 動機

你可以通過定製一個通過的圖形編輯器框架和增加一些表示音符、休止符和五線譜的新物件來構造一個樂譜編輯器。這個編輯器框架可能有一個工具選擇板用於將這些音樂物件加到樂譜中。這個選擇板可能還包括選擇、移動和其他操縱音樂物件的工具。使用者可以點選音符並使用它將四分音符加到樂譜中。或者它們可以使用移動工具在五線譜上下移動一個音符,從而改變它的音調。

我們假定該框架為音符和五線譜這樣的圖形構件提供了一個抽象的Graphics類。此外,為定義選擇板中的那些工具,還提供了抽象類Tool。該框架還建立圖形物件例項並將它們加入到文件中的工具預定義了一個GraphicTool子類。

但GraphicTool給框架設計者帶來一個問題,音符和五線譜的類特定於我們的應用,而GraphicTool類卻屬於框架。GraphicTool不知道如何建立我們的音樂類的例項,並將它們新增到樂譜中。我們可以為每一個音樂物件的類別上有所不同。我們知道物件複合是比建立子類更靈活的一種選擇,問題是,該框架怎麼樣用它來引數化GraphicTool的例項,而這些例項是由Graphic類所支援建立的。

解決辦法是讓GraphicTool通過拷貝或者克隆Graphic子類的一個例項來建立新的Graphic,我們稱這個例項為一個原型。GraphicTool將它應該克隆和新增到文件中的原型作為引數。如果所有Graphic子類都支援一個Clone操作,那麼GraphicTool可以克隆所有種類的Graphic,如下圖所示:


3596546-f15d4c82de64a775.png
image.png

因此在我們的音樂編輯器中,用於建立音樂物件的每一種工具都是一個不同原型進行初始化的GraphicTool例項,通過Clone一個音樂物件的原型並將這個Clone新增到樂譜中,每一個GraphicTool例項都會產生一個音樂物件。

我們甚至可以進一步使用Prototype模式來減少類的數目。我們使用不同的類來表示全音符和半音符,但可能不需要這麼做。它們可以是使用不同點陣圖和時延初始化的相同的類的例項。一個建立全音符的工具就是這樣的GraphicTool,它的原型是一個被初始化成全音符的MusicalNote。這可以極大的減少系統種類的數目,同時也更易於在音樂編輯器中增加新的樂符。

3 適用性

當一個系統應該獨立於它的產品建立、構成和表示時,要使用Prototype模式
- 當要例項化的類是在執行時刻指定時,例如通過動態載入
- 為了避免建立一個與產品層次平行的工廠類層次時
- 當一個類的例項只能有幾個不同狀態組合中的一種時,建立相應數目的原型並克隆它可能比每次用合適的狀態手工例項化該類更方便一些。

4 結構
3596546-0b9ca51fbdd9275f.png
image.png
5 參與者
- Prototype(Graphic)——宣告一個克隆自身的介面
- ConcretePrototype(Staff、WholeNote、HalfNote)——實現一個克隆自身的操作
- Client(GraphicTool)——讓一個原型克隆自身從而建立一個新的物件
6 協作

客戶請求一個原型克隆自身

7 效果
- 1.執行時刻增加和刪除產品;
- 2.改變值以指定新物件;
- 3.改變結構以指定新物件;
- 4.減少子類的構造;
- 5.用類動態配置應用;
8 實現

當實現原型時,要考慮下面一些問題
- 1 使用一個原型管理器:當一個系統中原型數目不固定時(也就是說,它們可以動態建立和銷燬),要保持一個可用原型的登錄檔;
- 2 實現克隆操作Prototype模式最困難的部分在於正確實現 Clone操作。當物件結構包含迴圈引用時,這尤為棘手。
- 3 初始化克隆物件

9 程式碼示例

github地址

相關文章