中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Prototype原型模式怎么實現

發布時間:2022-03-25 10:48:21 來源:億速云 閱讀:180 作者:iii 欄目:web開發

本篇內容介紹了“Prototype原型模式怎么實現”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!

Prototype(原型模式)

Prototype(原型模式)屬于創建型模式,既不是工廠也不是直接 New,而是以拷貝的方式創建對象。

意圖:用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。

舉例子

如果看不懂上面的意圖介紹,沒有關系,設計模式需要在日常工作里用起來,結合例子可以加深你的理解,下面我準備了三個例子,讓你體會什么場景下會用到這種設計模式。

做鑰匙

很顯然,為了房屋安全,要盡量做到一把鑰匙只能開一扇門,每把鑰匙結構都多多少少不一樣,卻又很相似,做鑰匙的人按照你給的鑰匙一模一樣做一個新的,這屬于什么模式呢?

兩種狀態表

當網站做不停機維護時,假設維護內容是給每個高級會員賬戶多打 100 元現金,現在需要改數據庫表。已知:

數據庫表有幾千萬條數據,其中高級會員有幾千位,為了方便調用已經緩存在中間層了,且數據庫對應 ID 更新后對應緩存也會更新。

幾千條數據修改語句執行完需要幾分鐘,這幾分鐘內無法接受用戶數據不同步的問題。

一種常見的做法是,我們生成一份高級會員列表的拷貝,代替數據庫緩存的結果,數據庫只要讀到對應會員 ID 就從拷貝列表中獲取,數據表新增一列狀態標志,操作完后這個拷貝移除,更新高級會員緩存。

但是如何生成高級會員列表拷貝呢?如果直接從幾千萬條用戶數據中重新查詢,會有較高的數據庫查詢成本。

模版組件

通用搭建系統中,我們可以將某個拖拽到頁面的區塊設置為 “模版”,這個模版可以作為一個新組件被重新拖拽到任意為止,實例化任意次。實際上,這是一種分段式復制粘貼,你會如何實現這個功能呢?

意圖解釋

解決上面問題的辦法都很簡單,就是基于已有對象進行復制即可,效率比 New 一個,或者工廠模式都要高。

意圖:用原型實例指定創建對象的種類,并且通過拷貝這些原型創建新的對象。

所謂原型實例,就是被選為拷貝模版的那個對象,比如做鑰匙例子中,你給老板的樣板鑰匙;兩種狀態表中的已有緩存高級會員列表;模版組件中選中的那個組件。然后,通過拷貝這些原型創建你想要的對象即可。

我們抽象思考一下,如果每把鑰匙都遵循 Prototype 接口,提供了 clone() 方法以復制自己,那就可以快速復制任意一把鑰匙。鑰匙工廠可無法解決每把鑰匙不一樣的問題,我們要的就是和某個鑰匙一模一樣的副本,復制一份鑰匙最簡單。

高級會員狀態表例子中,查詢數據庫的成本是高昂的,但如果僅僅復制已經查詢好的列表,時間可以忽略不計,因此最經濟的方案是直接復制,而不是通過工廠模式重新連接數據庫并執行查詢。

模版組件更是如此,我們根本沒有定義那么多組件實例的基類,只要每個組件提供一個 clone() 函數,就可以立即復制任意組件實例,這無疑是最經濟實惠的方案。

看到這里,你應該知道了,原型模式的精髓是對象要提供 clone() 方法,而這個 clone() 方法實現難度有高有低。

一般來說,原型模式的拷貝建議用深拷貝,畢竟新對象最好不要影響到舊對象,但是在深拷貝性能問題較大的情況下,可以考慮深淺拷貝結合,也就是將在新對象中,不會修改的數據使用淺拷貝,可能被修改的數據使用深拷貝。

結構圖

Client 是發出指令的客戶端,Prototype 是一個接口,描述了一個對象如何克隆自身,比如必須擁有 clone() 方法,而 ConcretePrototype 就是克隆具體的實現,不同對象有不同的實現來拷貝自身。

代碼例子

下面例子使用 typescript 編寫。

class Component implements Prototype {

  /**

   * 組件名

   */

  private name: string

  /**

   * 組件版本

   */

  private version: string

  /**

   * 拷貝自身

   */

  public clone = () => {

    // 構造函數省略了,大概就是傳遞 name 和 version

    return new Component(this.name, this.version)

  }

}

我們可以看到,實現了 Prototype 接口的 Component 必須實現 clone 方法,這樣任意組件在執行復制時,就可以直接調用 clone 函數,而不用關心每個組件不同的實現方式了。

從這就能看出,原型模式與 Factory 與 Builder 模式還是有類似之處的,在隱藏創建對象細節這一點上。

使用的時候,我們就可以這樣創建一個新對象:

const newComponent = oldComponent.clone()

這里有兩個注意點:一般來說,如果要二次修改生成的對象,不建議給 clone 函數加參數,因為這樣會導致接口的不一致。 我們可以為對象實例提供一些 set 函數進行二次修改。另外,clone 函數要考慮性能,就像前面說過的,可以考慮深淺拷貝結合的方式,同時要注意當對象存在引用關系甚至循環引用時,甚至不一定能實現拷貝函數。

弊端

每個設計模式必有弊端,但就像每一期都說的,有弊端不代表設計模式不好用,而是指在某種場景喜愛存在問題,我們只要規避這些場景,在合理的場景使用對應設計模式即可。

原型模式的弊端:

每個類都要實現 clone 方法,對類的實現是有一定入侵的,要修改已有類時,違背了開閉原則。

當類又調用了其他對象時,如果要實現深拷貝,需要對應對象也實現 clone 方法,整體鏈路可能會特別長,實現起來比較麻煩。

“Prototype原型模式怎么實現”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

电白县| 郴州市| 玉田县| 德化县| 钟祥市| 临颍县| 陵川县| 桑日县| 明水县| 长顺县| 广平县| 永兴县| 特克斯县| 盱眙县| 渭源县| 枞阳县| 长寿区| 苗栗县| 宣化县| 临海市| 商河县| 苍山县| 天门市| 宜宾市| 合江县| 长乐市| 建瓯市| 锦州市| 永宁县| 罗定市| 伊春市| 荃湾区| 英山县| 天镇县| 扎囊县| 沂水县| 水富县| 临漳县| 仁化县| 新竹县| 尤溪县|