盤點android中常見的設計模式(三) -- 原型模式

簡介:

開閉原則

今天來說一下設計模式的6大原則之一的開閉原則。開閉原則是由勒蘭特·梅耶在1988年的著作《面向對象軟件構造》中首先提出的,其中提到了開閉原則的定義:對擴展開放,對修改關閉。即在程序需要進行拓展的時候,不能去修改原有的代碼,實現一個熱插拔的效果。簡言之,是爲了使程序的擴展性好,易於維護和升級。

那麼開閉原則怎麼實現呢?可以通過“抽象約束、封裝變化”來實現開閉原則,即通過接口或者抽象類爲軟件實體定義一個相對穩定的抽象層,而將相同的可變因素封裝在相同的具體實現類中。

原型模式:

原型模式(Prototype Pattern)是用於創建重複的對象,同時又能保證性能。這種類型的設計模式屬於創建型模式,它提供了一種創建對象的最佳方式。

原型模式的運用場景一般分爲兩種:

  • 防止自己的實例在傳入別的模塊後,發生意外的修改。進行一次拷貝,再將該實例傳遞給別的模塊,可以有效的避免意外的篡改,始終保持該實例的原始性。
  • 爲了提高效率,很多時候我們需要大量的獲取一個對象相同的實例,通過原型模式“克隆”出一個內部屬性一樣的對象是個好的選擇,因爲類的初始化需要耗費很多的資源。

Android中的使用:

原型模式在android中有很多運用,如常見的Intent就實現了原型模式。

      Intent intent = new Intent(PrototypeDesignActivity.this,BuilderDesignActivity.class);
      Intent cloneIntent = (Intent) intent.clone();

那麼原型模式是如何實現的呢?首先需要對該類實現Cloneable接口,接着去重寫clone()方法,最後在clone()方法中實現類的拷貝。

public class Intent implements Parcelable, Cloneable {
    ......

    @Override
    public Object clone() {
        return new Intent(this);
    }

    ......

}

需要注意的是,重寫的clone()方法並不是Cloneable接口中的,因爲該接口是一個空接口。

/**
 * @author  unascribed
 * @see     java.lang.CloneNotSupportedException
 * @see     java.lang.Object#clone()
 * @since   JDK1.0
 */
public interface Cloneable {
}

其實通過Cloneable接口的註釋我們也能知道clone()方法是來自於Object類。並告訴我們有關重寫此方法的詳細信息請參見Object.clone()方法。

    /**
     * @return     a clone of this instance.
     * @exception  CloneNotSupportedException  if the object's class does not
     *               support the {@code Cloneable} interface. Subclasses
     *               that override the {@code clone} method can also
     *               throw this exception to indicate that an instance cannot
     *               be cloned.
     * @see java.lang.Cloneable
     */
    protected Object clone() throws CloneNotSupportedException {
        if (!(this instanceof Cloneable)) {
            throw new CloneNotSupportedException("Class " + getClass().getName() +
                                                 " doesn't implement Cloneable");
        }

        return internalClone();
    }

內容很簡單,首先判斷是否實現了Cloneable接口,如果沒有實現就重寫此方法,最終會拋出CloneNotSupportedException異常。如果實現過這個類最終返回internalClone()方法。

    /*
     * Native helper method for cloning.
     */
    private native Object internalClone();

最終我們可以看到這是一個native方法,用於輔助clone。

 

補充:

深拷貝與淺拷貝

我們知道java中分爲基本數據類型和引用數據類型,深淺拷貝就是針對引用數據類型所說的。舉個栗子:假如我們用對象A的clone()方法複製了對象B。這時候我們修改A中的某個引用數據類型的屬性,這個時候B也跟着改變了,那麼這種拷貝方式就是淺拷貝,如果B相對於A是獨立的對象,不受到A中任何屬性的影響,即A,B中相同的引用所指的地址不同,那麼這種就是深拷貝。

常用的實現深拷貝的方式有:遞歸、利用JSON轉換對象、利用Serializable或者Parcelable實現序列化來實現。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章