簡介android
裝飾模式、代理模式、適配器模式我的感受很是類似,三者的類圖也差很少,很差理解。設計模式
區別:iphone
裝飾模式:原有功能不能知足現有需求,按照開閉原則的思路,咱們經過擴展接口來加強功能。能夠裝飾多層ide
代理模式:經過代理對象來控制訪問另外一個對象(被代理對象)的方法,不對該方法進行直接操做。函數
適配器模式:解決接口不匹配的問題。測試
下面經過簡單的例子具體說明。this
(1)裝飾模式spa
場景描述以下:現有接口Car,擁有方法run,其實現類爲BMWCar。設計
public interface Car { public void run(); }
public class BMWCar implements Car { @Override public void run() { System.out.println("BMW running!"); } }
測試場景以下代理
public class Client { public static void main(String[] args) { Car car = new BMWCar(); car.run(); } }
輸出:「BMW running!」
如今需求變了,要求BMWCar在run以前要說一句「Heihei, I am BMW!」(加強功能)。一般狀況不建議改變現有的代碼,對修改關閉對擴展開放(開閉原則),可行的方案是擴展一個裝飾者DecorateCar,DecorateCar也實現了Car接口,並持有Car的引用,而後經過構造函數實例化。
public class DecorateCar implements Car { private Car car; public DecorateCar(Car car){ this.car = car; } @Override public void run() { System.out.println("Hiahia, I am BMW!"); car.run(); } }
測試場景以下:
public class Client { public static void main(String[] args) { Car car = new DecorateCar(new BMWCar()); car.run(); } }
輸出爲:
Hiahia, I am BMW!
BMW running!
(2)代理模式
場景:超級明星都有經紀人,若想邀請該明星演出必須經過經紀人,而後經紀人根據明星的日程表來安排演出,若日程表爲滿,則拒絕本次邀請。
超級明星能夠用SuperStar接口表示,具體的明星類如歌手用Singer實現SuperStar。經紀人就是代理,用StarProxy表示。
public interface SuperStar { public void perform(); }
public class Singer implements SuperStar { @Override public void perform() { System.out.println("singing a song!"); } }
public class StarProxy implements SuperStar { private SuperStar superStar; private boolean busyState; public StarProxy(boolean busyState){ superStar = new Singer(); this.busyState = busyState; } @Override public void perform() { if (busyState){ superStar.perform(); }else{ System.out.println("行程已滿,沒法演出"); } } }
這裏經過代理對象控制訪問,當busyState爲true時,經紀人(代理)安排明星(被代理)演出,不然不能演出。測試場景以下
public class Client { public static void main(String[] args) { SuperStar superStar = new StarProxy(true); superStar.perform(); superStar = new StarProxy(false); superStar.perform(); } }
輸出:
singing a song!
行程已滿,沒法演出
咋一看,真感受代理模式和裝飾模式沒啥區別。可是,請注意兩個模式的使用場景不同,裝飾模式目的是添加新的功能,能夠裝飾不少層,如Java IO就是典型的應用。代理模式通常只代理一次,通常用做控制訪問。其實也不用糾結設計模式的名稱,咱們知道這一類問題如何解決不就ok了。
(3)適配器模式
場景:衆所周知安卓手機使用安卓充電器(typeC接頭),蘋果手機使用蘋果充電器(iphone接頭)。如今你有一臺安卓手機和一個蘋果充電器,怎麼給手機充電。
答案:使用轉接頭(適配器)將iphone接頭轉爲typeC接頭,就能夠用蘋果充電器給安卓手機充電。
安卓充電器經過typeC給手機充電。
public interface AndroidCharger { public void typeC(); }
public class AndroidChargerImpl implements AndroidCharger { @Override public void typeC() { System.out.println("我能給手機充電"); } }
蘋果充電器經過iphone給手機充電。
public interface IphoneCharger { public void iphone(); }
public class IphoneChargerImpl implements IphoneCharger { @Override public void iphone() { System.out.println("我能給手機充電"); } }
適配器就是拿蘋果充電器看成安卓充電器使用,這樣咱們就能夠經過info來充電。
public class IphoneAdapter implements AndroidCharger { private IphoneCharger iphoneCharger; public IphoneAdapter(IphoneCharger iphoneCharger){ this.iphoneCharger = iphoneCharger; } @Override public void typeC() { iphoneCharger.iphone(); } }
測試場景以下
public class Client { public static void main(String[] args) { IphoneCharger iphoneCharger = new IphoneChargerImpl(); AndroidCharger androidCharger = new IphoneAdapter(iphoneCharger); androidCharger.typeC(); } }
有一個蘋果充電器,而後將其適配成安卓充電器,經過typeC來充電。輸出以下:
我能給手機充電
------------------------完-------------------------