Go設計模式之原型模式圖文詳解
原型模式
原型模式是一種創(chuàng)建型設計模式, 使你能夠復制已有對象, 而又無需使代碼依賴它們所屬的類。
所有的原型類都必須有一個通用的接口, 使得即使在對象所屬的具體類未知的情況下也能復制對象。 原型對象可以生成自身的完整副本, 因為相同類的對象可以相互訪問對方的私有成員變量。
問題
如果你有一個對象, 并希望生成與其完全相同的一個復制品, 你該如何實現(xiàn)呢? 首先, 你必須新建一個屬于相同類的對象。 然后, 你必須遍歷原始對象的所有成員變量, 并將成員變量值復制到新對象中。
不錯! 但有個小問題。 并非所有對象都能通過這種方式進行復制, 因為有些對象可能擁有私有成員變量, 它們在對象本身以外是不可見的。
“從外部” 復制對象并非總是可行。
直接復制還有另外一個問題。 因為你必須知道對象所屬的類才能創(chuàng)建復制品, 所以代碼必須依賴該類。 即使你可以接受額外的依賴性, 那還有另外一個問題: 有時你只知道對象所實現(xiàn)的接口, 而不知道其所屬的具體類, 比如可向方法的某個參數(shù)傳入實現(xiàn)了某個接口的任何對象。
解決方案
原型模式將克隆過程委派給被克隆的實際對象。 模式為所有支持克隆的對象聲明了一個通用接口, 該接口讓你能夠克隆對象, 同時又無需將代碼和對象所屬類耦合。 通常情況下, 這樣的接口中僅包含一個 克隆
方法。
所有的類對 克隆
方法的實現(xiàn)都非常相似。 該方法會創(chuàng)建一個當前類的對象, 然后將原始對象所有的成員變量值復制到新建的類中。 你甚至可以復制私有成員變量, 因為絕大部分編程語言都允許對象訪問其同類對象的私有成員變量。
支持克隆的對象即為原型。 當你的對象有幾十個成員變量和幾百種類型時, 對其進行克隆甚至可以代替子類的構造。
預生成原型可以代替子類的構造。
其運作方式如下: 創(chuàng)建一系列不同類型的對象并不同的方式對其進行配置。 如果所需對象與預先配置的對象相同, 那么你只需克隆原型即可, 無需新建一個對象。
真實世界類比
現(xiàn)實生活中, 產品在得到大規(guī)模生產前會使用原型進行各種測試。 但在這種情況下, 原型只是一種被動的工具, 不參與任何真正的生產活動。
一個細胞的分裂。
由于工業(yè)原型并不是真正意義上的自我復制, 因此細胞有絲分裂 (還記得生物學知識嗎?) 或許是更恰當?shù)念惐取?有絲分裂會產生一對完全相同的細胞。 原始細胞就是一個原型, 它在復制體的生成過程中起到了推動作用。
原型模式結構
基本實現(xiàn)
- 原型 (Prototype) 接口將對克隆方法進行聲明。 在絕大多數(shù)情況下, 其中只會有一個名為
clone
克隆的方法。 - 具體原型 (Concrete Prototype) 類將實現(xiàn)克隆方法。 除了將原始對象的數(shù)據復制到克隆體中之外, 該方法有時還需處理克隆過程中的極端情況, 例如克隆關聯(lián)對象和梳理遞歸依賴等等。
- 客戶端 (Client) 可以復制實現(xiàn)了原型接口的任何對象。
原型注冊表實現(xiàn)
- 原型注冊表 (Prototype Registry) 提供了一種訪問常用原型的簡單方法, 其中存儲了一系列可供隨時復制的預生成對象。 最簡單的注冊表原型是一個
名稱 → 原型
的哈希表。 但如果需要使用名稱以外的條件進行搜索, 你可以創(chuàng)建更加完善的注冊表版本。
偽代碼
在本例中, 原型模式能讓你生成完全相同的幾何對象副本, 同時無需代碼與對象所屬類耦合。
克隆一系列位于同一類層次結構中的對象。
所有形狀類都遵循同一個提供克隆方法的接口。 在復制自身成員變量值到結果對象前, 子類可調用其父類的克隆方法。
原型模式適合應用場景
如果你需要復制一些對象, 同時又希望代碼獨立于這些對象所屬的具體類, 可以使用原型模式。
這一點考量通常出現(xiàn)在代碼需要處理第三方代碼通過接口傳遞過來的對象時。 即使不考慮代碼耦合的情況, 你的代碼也不能依賴這些對象所屬的具體類, 因為你不知道它們的具體信息。
原型模式為客戶端代碼提供一個通用接口, 客戶端代碼可通過這一接口與所有實現(xiàn)了克隆的對象進行交互, 它也使得客戶端代碼與其所克隆的對象具體類獨立開來。
如果子類的區(qū)別僅在于其對象的初始化方式, 那么你可以使用該模式來減少子類的數(shù)量。 別人創(chuàng)建這些子類的目的可能是為了創(chuàng)建特定類型的對象。
在原型模式中, 你可以使用一系列預生成的、 各種類型的對象作為原型。
客戶端不必根據需求對子類進行實例化, 只需找到合適的原型并對其進行克隆即可。
實現(xiàn)方式
創(chuàng)建原型接口, 并在其中聲明
克隆
方法。 如果你已有類層次結構, 則只需在其所有類中添加該方法即可。原型類必須另行定義一個以該類對象為參數(shù)的構造函數(shù)。 構造函數(shù)必須復制參數(shù)對象中的所有成員變量值到新建實體中。 如果你需要修改子類, 則必須調用父類構造函數(shù), 讓父類復制其私有成員變量值。
如果編程語言不支持方法重載, 那么你可能需要定義一個特殊方法來復制對象數(shù)據。 在構造函數(shù)中進行此類處理比較方便, 因為它在調用
new
運算符后會馬上返回結果對象。克隆方法通常只有一行代碼: 使用
new
運算符調用原型版本的構造函數(shù)。 注意, 每個類都必須顯式重寫克隆方法并使用自身類名調用new
運算符。 否則, 克隆方法可能會生成父類的對象。你還可以創(chuàng)建一個中心化原型注冊表, 用于存儲常用原型。
你可以新建一個工廠類來實現(xiàn)注冊表, 或者在原型基類中添加一個獲取原型的靜態(tài)方法。 該方法必須能夠根據客戶端代碼設定的條件進行搜索。 搜索條件可以是簡單的字符串, 或者是一組復雜的搜索參數(shù)。 找到合適的原型后, 注冊表應對原型進行克隆, 并將復制生成的對象返回給客戶端。
最后還要將對子類構造函數(shù)的直接調用替換為對原型注冊表工廠方法的調用。
原型模式優(yōu)缺點
你可以克隆對象, 而無需與它們所屬的具體類相耦合。
你可以克隆預生成原型, 避免反復運行初始化代碼。
你可以更方便地生成復雜對象。
你可以用繼承以外的方式來處理復雜對象的不同配置。
克隆包含循環(huán)引用的復雜對象可能會非常麻煩。
代碼示例
Go設計模式之原型模式講解和代碼示例_Golang_腳本之家 (jb51.net)
以上就是Go設計模式之原型模式圖文詳解的詳細內容,更多關于Go原型模式的資料請關注腳本之家其它相關文章!
相關文章
Go語言開發(fā)kube-scheduler整體架構深度剖析
這篇文章主要為大家介紹了Go語言開發(fā)kube-scheduler整體架構深度剖析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪2023-04-04