今天看了一篇很棒的介紹裝飾者模式的文章,因而就按照以往的慣例,學習了以後手動的碼了這麼一篇隨記記錄本身的體會,而且參考原文的例子,本身手動的實現了一遍整個demo,原文地址爲:http://blog.csdn.net/zhaoyanjun6/article/details/56488020ide
首先咱們來大致瞭解一下裝飾者模式到底是個什麼東西呢?所謂的裝飾者,能夠參考如今很火的一個遊戲——絕地大逃殺裏頭的槍械自由改裝的概念來解釋裝飾者模式的概念。如今有這麼一把AK47槍,除了槍以外,沒有任何之外的配件,看到人就只能拿着把裸的AK隨便的突突突,碰運氣看看能不能打中人。而忽然該玩家得到了一個八倍瞄準鏡,和一個消聲器,這時候該玩家就能夠把這個瞄準鏡和消聲器安裝到AK上,而後他就能夠用這把AK的八倍鏡去瞄準2000米外的敵人,而後用AK上的消聲器,悄無聲息的擊殺別人。而這時候,這個玩家用膩了AK,因而又把這個瞄準鏡和消聲器安裝到了本身的沙漠飛鷹的手槍上,這時候,這個沙漠飛鷹就具備了和AK的同樣的功能。這個就是咱們所謂的裝飾者模式,經過裝飾器裝飾以後,咱們的目標就會具備一個新的功能。性能
那麼瞭解了裝飾者模式是什麼以後,它的好處就更一目瞭然了吧?在拓展一個類的功能的時候,一般可使用繼承來實現功能的拓展,若是這些須要拓展的功能的種類很繁多,那麼勢必生成不少子類,增長系統的複雜性,同時,使用繼承實現功能拓展,咱們必須可預見這些拓展功能,這些功能是編譯時就肯定了,是靜態的。而經過裝飾者模式來作這個事情,就能夠完美的解決這些問題。就用咱們剛剛那個例子來講,若是經過繼承來實現的話,那麼勢必AK47下會有這麼些子類,帶瞄準鏡的AK,帶消聲器的AK,帶瞄準鏡和消聲器的AK,這就很蛋疼咯吧?並且若是要用在沙漠飛鷹之上,又要有帶瞄準鏡的沙漠飛鷹子類等,會有無數的子類出現。學習
二話不說 ,那麼接下來咱們先來看看代碼測試
先看看被裝飾者的代碼:this
public interface Gun { void status(); } public class AK47 implements Gun { @Override public void status() { System.out.println("當前AK沒有任何配件"); } } public class DesertEagle implements Gun { @Override public void status() { System.out.println("當前沙漠飛鷹沒有任何配件"); } }
被裝飾者都共同實現了一個叫GUN的接口(AK和沙漠飛鷹都屬於槍,在這個接口下有一個方法叫status表示當前該槍具備什麼配件),接下來看看咱們的裝飾器類:spa
public abstract class GunPart implements Gun { Gun gun; public GunPart(Gun gun) { this.gun=gun; } @Override public void status() { gun.status(); } } public class muffler extends GunPart { public muffler(Gun gun) { super(gun); } @Override public void status() { super.status(); say(); } public void say() { System.out.println("該槍有了消聲器"); } } public class telescope extends GunPart { public telescope(Gun gun) { super(gun); // TODO Auto-generated constructor stub } @Override public void status() { // TODO Auto-generated method stub super.status(); say(); } public void say() { System.out.println("該槍有了瞄準鏡"); } }
在裝飾器當中,咱們抽象了這麼一個抽象類叫作GunPart,而不管是消聲器仍是瞄準鏡都是屬於GunPart(槍械配件的一部分)因此都是繼承了這個GunPart,而這個GunPart同時也實現了Gun這個接口,注意這裏是重點,這個GunPart必定也要實現這個Gun接口,不然就沒法實現裝飾器可疊加的效果了。而繼承了GunPart的子類,都會重寫父類的status方法,重寫的內容第一行必定是調用父類的.status方法。而後再加上該子類添加的特點功能,在例子中是say()方法。.net
接下來看看咱們的測試代碼和測試結果:代理
public class test { public static void main(String[] args) { // TODO Auto-generated method stub Gun AK47=new AK47(); muffler muffler=new muffler(AK47); telescope telescope=new telescope(muffler); telescope.status(); System.out.println(); Gun DS=new DesertEagle(); muffler muffler1=new muffler(DS); telescope telescope1=new telescope(muffler1); telescope1.status(); } }
當前AK沒有任何配件
該槍有了消聲器
該槍有了瞄準鏡
當前沙漠飛鷹沒有任何配件
該槍有了消聲器
該槍有了瞄準鏡
這樣,咱們一個完整的裝飾者模式的demo就寫完了,那麼咱們來試着總結一下裝飾者模式的一些重點,首先看看這個繼承和實現關係圖:調試
總的來講,裝飾模式下降系統的耦合度,能夠動態的增長或刪除對象的責任(在寫test類的方法的時候,動態的添加或者不添加),並使得須要裝飾的具體構建類和具體裝飾類能夠獨立變化,以便增長新的具體構建類和具體裝飾類。code
那麼裝飾者模式講到這裏,就差很少。。。。。。。。。。。。。。。殼鬥麻袋~!!!!你看到這裏確定會忽然發覺,誒?這個裝飾者模式怎麼特麼的和靜態代理那麼像啊?
1.一樣都是加強類(裝飾器)和目標類(被裝飾者)實現了同一個接口。
2.一樣都是經過加強類(裝飾器)重寫和目標類(被裝飾者)來加強方法。
這特麼不是同樣的嘛?
其實我看到這裏的時候,也產生了這麼一個疑問,因而就去查閱了其餘關於代理模式和裝飾者模式,因而獲得瞭如下三點:
1.裝飾器模式關注於在一個對象上動態的添加方法,然而代理模式關注於控制對對象的訪問。
2.裝飾器模式能夠疊加的爲被裝飾者裝飾,而代理不支持多層嵌套。這也是我爲何在前邊「劃重點」的緣由。
好啦,具體的仍是本身體會吧。(其實本身這一塊也還不大會,一塊兒學習咯)