裝飾模式、代理模式、適配器模式

簡介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來充電。輸出以下:

我能給手機充電

 

------------------------完-------------------------

相關文章
相關標籤/搜索