1. 程式人生 > >Android設計模式之裝飾器模式

Android設計模式之裝飾器模式

       截止目前為止,我已經學了四個設計模式了,首先回顧一下這幾天學習設計模式的感悟,第一個接觸的當然就是單例模式了,單例模式由於將構造方法私有化,因此在類的外面不能創造該類的物件,那麼問題來了,那我們就在類的裡面得到該類的物件,且該類的物件而且是唯一的,就是這樣。接著學習了責任鏈模式,責任鏈模式不用多說,就是一條鏈式結構,該模式的核心思想就是將職責沿著一條鏈式結構進行傳遞。接著就是原型模式,原型模式感覺學起來還是有點複雜,就是使用Java提供的介面函式cloneable函式,實現其中的方法clone方法,今天接觸的是裝飾模式,對我之前的設計模式不太瞭解的同學可以觀看我之前的部落格。

今天我們步入正題吧,裝飾模式

一、裝飾模式的定義

      接下來我們首先談一下裝飾模式的概念,如果我們想要對一個類的功能進行擴充套件,一般採用繼承的方式,但是在Java語言中,是不支援的多繼承的,那麼問題來了,我們就需要使用裝飾模式,裝飾模式是為了解決多繼承一種思路。我們將會在接下來的URL圖中詳細觀看。

   

Component(抽象構件):它是具體構件和抽象裝飾類的共同父類,聲明瞭在具體構件中實現的業務方法,它的引入可以使客戶端以一致的方式處理未被裝飾的物件以及裝飾之後的物件,實現客戶端的透明操作。

 ConcreteComponent(具體構件):它是抽象構件類的子類,用於定義具體的構件物件,實現了在抽象構件中宣告的方法,裝飾器可以給它增加額外的職責(方法)。

 Decorator(抽象裝飾類):它也是抽象構件類的子類,用於給具體構件增加職責,但是具體職責在其子類中實現。它維護一個指向抽象構件物件的引用,通過該引用可以呼叫裝飾之前構件物件的方法,並通過其子類擴充套件該方法,以達到裝飾的目的。

 ConcreteDecorator(具體裝飾類):它是抽象裝飾類的子類,負責向構件新增新的職責。每一個具體裝飾類都定義了一些新的行為,它可以呼叫在抽象裝飾類中定義的方法,並可以增加新的方法用以擴充物件的行為。

這裡借用劉偉作者的URL圖,希望作者不要介意,推薦大家可以學習劉偉的設計模式那本書,非常值得學習。

二、具體事例

接下來我用程式碼為大家做簡要介紹

欲開發了一個數據加密模組,可以對字串進行加密。最簡單的加密演算法通過對字母進行移位來實現,同時還提供了稍複雜的逆向輸出加密,還提供了更為高階的求模加密。使用者先使用最簡單的加密演算法對字串進行加密,如果覺得還不夠可以對加密之後的結果使用其他加密演算法進行二次加密,當然也可以進行第三次加密。試使用裝飾模式設計該多重加密系統。

那麼我們首先設計一個抽象類作為根基

package director;

public abstract class EncryptComponet {

	public abstract void encrypt();
}
這個就是抽象類,裝飾類繼承於他
package director;

public class ConcreteEncrypt extends EncryptComponet {

	private EncryptComponet encryptComponet;
	public ConcreteEncrypt(EncryptComponet encryptComponet) {
		super();
		this.encryptComponet = encryptComponet;
	}
	public void encrypt() {
		// TODO Auto-generated method stub
		encryptComponet.encrypt();
	}

}

大家看到了沒有,我們傳遞了抽象的父類進來,作為物件使用,接下來我們下裝飾的具體子類實現
package director;

public class TranslateEncrypt extends ConcreteEncrypt {

	public TranslateEncrypt(EncryptComponet encryptComponet) {
		super(encryptComponet);
		// TODO Auto-generated constructor stub
		addTranslateEncrypt();
	}

	private void addTranslateEncrypt() {
		// TODO Auto-generated method stub
		System.out.println("移動加密");
	}

}

這是對資料的一次加密,我們還可以繼續繼承裝飾類
package director;

public class ReversEncrypt extends ConcreteEncrypt {

	public ReversEncrypt(EncryptComponet encryptComponet) {
		super(encryptComponet);
		// TODO Auto-generated constructor stub
		addReservesEncrypt();
	}

	private void addReservesEncrypt() {
		// TODO Auto-generated method stub
		System.out.println("反向加密");
	}

}
哈哈,不用多說了,接下來是三次加密的程式碼
package director;

public class SuperEncrypt extends ConcreteEncrypt {

	public SuperEncrypt(EncryptComponet encryptComponet) {
		super(encryptComponet);
		// TODO Auto-generated constructor stub
		addSuperEncrypt();
	}

	private void addSuperEncrypt() {
		// TODO Auto-generated method stub
		System.out.println("最高加密演算法");
	}

}
package director;

public class RawData extends EncryptComponet {

	public void encrypt() {
		// TODO Auto-generated method stub
		System.out.println("這是要傳送的資料");
	}

}
package director;


public class Client {


	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		EncryptComponet ss,abc1,abc2,abc3;
		ss = new RawData();
		abc1 = new TranslateEncrypt(ss);
		//abc1.encrypt();
		abc2 = new ReversEncrypt(abc1);
		//abc2.encrypt();
		abc3 = new SuperEncrypt(abc2);
		abc3.encrypt();
	}


}


上面就是所有程式碼的實現

由於剛開始寫技術部落格,很多地方寫的不到位,望大家多多指導

三、裝飾模式使用場景

在以下情況下可以考慮使用裝飾模式:

(1) 在不影響其他物件的情況下,以動態、透明的方式給單個物件新增職責。

(2) 當不能採用繼承的方式對系統進行擴充套件或者採用繼承不利於系統擴充套件和維護時可以使用裝飾模式。不能採用繼承的情況主要有兩類:第一類是系統中存在大量獨立的擴充套件,為支援每一種擴充套件或者擴充套件之間的組合將產生大量的子類,使得子類數目呈爆炸性增長;第二類是因為類已定義為不能被繼承(如Java語言中的final類)。