前面我們看了Decorator模式的一下理論基礎,知道了Decorator模式的適應場合是:在運行時刻由用戶動態決定加入的方式和時機,無法在編譯期間決定。下面我們就以一個實際的例子來了解一下Decorator模式的實際應用。
一、應用場景:
假設我們已經存在這樣的一個程序:
1).該程序從一個列表中拿出所有的用戶名單,然后逐個向用戶發送一句信息。
2).現在我們又增加了一個新的需求:在發送之前檢查一下該用戶是否存在于黑名單中,如果是的話則不發送給該用戶。
3).是否進行檢查則動態根據用戶的當時需要來決定。
二、需求分析:
從上面的情況分析,如果我們采用繼承的方式,重新編寫一個帶有過濾功能的發送程序,則必須完全改寫原有的發送方法,插入過濾的過程。如果我們采用Decorator模式的話,可以怎么做呢?
首先分析一下需求的公共部分,相同的部分都是發送信息,不管是否需要進行過濾。也就是說只有發送的方法拿到數據,它就不管三七二十一發出去了,所以這個功能應該可以被抽象成一個接口。
接下來我們來看一下,既然新的功能只是在舊的功能之前插入了“過濾”這一簡單的過程,原有的功能保持不變,所以我們完全可以把舊的功能委托給老的程序來進行。既然是委托了那么必然在新的類里面要含有一個舊的對象的引用。
最后如何實現“動態插入過濾功能”呢?我們看一下前面的接口,如果我們實現了接口,那么在其實現方法中就可以重寫原來的方法,增加過濾功能了。
三、系統設計:
我們來看一下下面這張圖,明確一下各個對象之間的聯系
在這張圖中我們看到:我們抽象出了一個接口:ISendMessage接口,原有的SendMessageImpl類和新增的SendMessageDecorator類都實現了該接口。Decorator類有一個對SendMessageImpl的委托。
四、詳細代碼:
·ISendMessage:







·SendMessageImpl:




























·SendMessageDecorator:
























































·DecoratorTest:







































五、Decorator模式的特點:
A. Decorator類實現了接口(抽象)
B. Decorator類中包含一個接口類型的屬性,并通過適當的方式被實例化
C. Decorator類中實現接口的抽象方法,委托父類屬性完成基本功能,同時加入額外功能或改變工作流
-------------------------------------------------------------
生活就像打牌,不是要抓一手好牌,而是要盡力打好一手爛牌。