設計模式之原型模式

前言

一個月更新一片博客哈,又來堅持了~java

以前給你們介紹了單例模式,此次在給你們介紹一個簡單的建立形的模式-原型模式編程

原型模式的定義

原型模式(Prototype Pattern):使用原型實例指定建立對象的種類,而且經過拷貝這些原型建立新的對象。原型模式是一種對象建立型模式。網絡

咱們看到這段的介紹,其實歸納起來就是複製一摸同樣的對象,這就是這個模型要作的事情啦~3d

再看一下原型模式的類圖:cdn

從上圖中能夠看到,原型模式的UML類圖主要角色就三個:Client 、 Prototype 和 Concrete Ptrototype對象

  • Prototype(抽象原型類):它是聲明克隆方法的接口,是全部具體原型類的公共父類,能夠是抽象類也能夠是接口,甚至還能夠是具體實現類。blog

  • ConcretePrototype(具體原型類):它實如今抽象原型類中聲明的克隆方法,在克隆方法中返回本身的一個克隆對象。繼承

  • Client(客戶類):讓一個原型對象克隆自身從而建立一個新的對象,在客戶類中只須要直接實例化或經過工廠方法等方式建立一個原型對象,再經過調用該對象的克隆方法便可獲得多個相同的對象。因爲客戶類針對抽象原型類Prototype編程,所以用戶能夠根據須要選擇具體原型類,系統具備較好的可擴展性,增長或更換具體原型類都很方便。接口

從上面咱們能夠看到原型模式的兩個核心:內存

  1. 須要實現抽象原型類的方法
  2. 須要自身實現克隆

原型模式的簡單實現

Java中全部的類都繼承Object類,咱們進入Object能夠看到,其內有一個clone()方法,能夠將一個java對象複製一份,如圖:

因此,咱們使用的時只須要實現一個標識接口Cloneable,表示這個Java類支持被複制。具體實現以下代碼:

以上就是實現原型模式的代碼,相對仍是比較簡單的~

咱們能夠看到要想得到一份對象的拷貝,能夠利用Object的clone方法

(1) 在派生類中覆蓋基類的clone()方法,並聲明爲public;

(2) 在派生類的clone()方法中,調用super.clone();

(3) 派生類需實現Cloneable接口。

說到拷貝對象,就要提到深拷貝和前拷貝了,深拷貝也就是解決咱們克隆的對象裏還有對象這種狀況。 解決的辦法就是重寫clone,在調用子類的克隆,便可以深拷貝。

那麼在這裏咱們就能看出原型模式的缺點

原型模式的缺點

  • 須要爲每個類配備一個克隆方法,並且該克隆方法位於一個類的內部,當對已有的類進行改造時,須要修改源代碼,違背了「開閉原則」。
  • 在實現深克隆時須要編寫較爲複雜的代碼,並且當對象之間存在多重的嵌套引用時,爲了實現深克隆,每一層對象對應的類都必須支持深克隆,實現起來可能會比較麻煩。

原型模式的優勢

  • 當建立新的對象實例較爲複雜時,使用原型模式能夠簡化對象的建立過程,經過複製一個已有實例能夠提升新實例的建立效率。
  • 擴展性較好,因爲在原型模式中提供了抽象原型類,在客戶端能夠針對抽象原型類進行編程,而將具體原型類寫在配置文件中,增長或減小產品類對原有系統都沒有任何影響。

原型模式的適用場景

  • 建立新對象成本較大(如初始化須要佔用較長的時間,佔用太多的CPU資源或網絡資源),新的對象能夠經過原型模式對已有對象進行復制來得到,若是是類似對象,則能夠對其成員變量稍做修改。
  • 若是系統要保存對象的狀態,而對象的狀態變化很小,或者對象自己佔用內存較少時,可使用原型模式配合備忘錄模式來實現。

總結

以上原型模式基本給你們介紹完了,在這裏在強調一下哈,其實,調用clone()構造對象時並不必定比new快,使用clone()仍是new來建立對象須要根據構造對象的成原本決定,若是對象的構形成本比較高或者構造比較麻煩,那麼使用clone()的效率比較高,不然使用new。因此也不是一味的爲了使用原型而使用原型模式哈~

相關文章
相關標籤/搜索