【設計模式Android】代理模式

設計模式Android 其餘相關文章:
【設計模式Android】設計模式六大原則javascript


定義:爲其餘對象提供一種代理以控制這個對象的訪問java

代理模式中的角色

Subject抽象主題

抽象主題能夠是一個抽象類也能夠是一個接口。設計模式

public interface  Subject{
    public void doSomeThing();
}複製代碼

RealSubject具體實例

被代理的角色,是邏輯的具體執行者。ide

public class RealSubject implements Subject{
    @Override
    public void doSomeThing() {
        //do some things
    }
}複製代碼

代理類

用來代理實際類執行邏輯post

public class Proxy implements Subject{
    private Subject subject = null;
    public Proxy(){
        subject = new RealSubject();
    }
    @Override
    public void doSomeThing() {
        subject.doSomeThing();
    }
}複製代碼

舉個例子

在這裏咱們舉這樣一個例子。
好比咱們在玩遊戲的時候但願找個代練,代替咱們升級打怪。這個這個代練就能夠認爲是一個代理。
咱們能夠簡單寫一下作個對比:ui

Subject抽象主題類

咱們在這裏定義一下游戲玩家的抽象行爲:this

public interface IGame {
     public void attack();
    public void move();
    public void dead();
    public void update();
}複製代碼

RealSubject真是主題類

在這裏咱們定義下玩家的實際行爲:spa

public class GamePlayer implements IGame {
    private String name;
    public GamePlayer(String name){
        this.name = name;
    }
    @Override
    public void attack() {
        System.out.println(name+"正在"+"攻擊");
    }

    @Override
    public void move() {
        System.out.println(name+"正在"+"行走");

    }

    @Override
    public void dead() {
        System.out.println(name+"已經"+"死亡");

    }

    @Override
    public void update() {
        System.out.println(name+"已經"+"升級");

    }
}複製代碼

代理類

如今須要找一個類替咱們去執行咱們要執行的行爲。設計

public class GamePlayerProxy implements IGame {
    private IGame player = null;
    public GamePlayerProxy(IGame player){
        this.player = player;
    }
    @Override
    public void attack() {
        player.attack();
    }

    @Override
    public void move() {
        player.move();
    }

    @Override
    public void dead() {
        player.dead();
    }

    @Override
    public void update() {
        player.update();
    }
}複製代碼

實例化執行

咱們如今看一下應該如何在程序中調用:代理

public class Main {
    public static void main(String[] args) {
            IGame player = new GamePlayer("deep");
            IGame proxy = new GamePlayerProxy(player);
            proxy.move();
            proxy.attack();
            proxy.update();
            proxy.dead();
    }
}複製代碼

爲何要用代理模式

有些開發者看了這篇文章可能會問,咱們在寫程序中,爲何要用代理模式,咱們直接商用上面提到的真是主題類RealSubject不就好了嗎?
能夠是能夠,可是不符合咱們以前提到過的設計原則(【設計模式Android】設計模式六大原則

隔離原則

在某些狀況下,一個對象不適合或者不能直接引用另外一個對象,而代理對象能夠在客戶端和目標對象之間起到中介的做用, 其特徵是代理類與委託類有一樣的接口。

開閉原則

代理類不單單是一個隔離客戶端和委託類的中介。咱們還能夠藉助代理來在增長一些功能,而不須要修改原有代碼,嚴重的複合開閉原則哦。

優勢:

  • 職責清晰,RealSubject只處理實際業務邏輯,不用關心其它。
  • 高擴展性,複合開閉原則,方便進行修改

拓展

普通代理

客戶端只訪問代理,不訪問真實角色。
就如同上文中舉的例子同樣。調用者只知道代理而不知道真實角色,咱們修改一下上面的例子:

public class GamePlayerProxy implements IGame {
    private IGame player = null;
    public GamePlayerProxy(String name){
        this.player = new GamePlayer(name);
    }
    @Override
    public void attack() {
        player.attack();
    }

    @Override
    public void move() {
        player.move();
    }

    @Override
    public void dead() {
        player.dead();
    }

    @Override
    public void update() {
        player.update();
    }
}複製代碼

修改一下調用,能夠看出:

public class Main {
    public static void main(String[] args) {

            IGame proxy = new GamePlayerProxy("deep");
            proxy.move();
            proxy.attack();
            proxy.update();
            proxy.dead();

    }
}複製代碼

強制代理

強制代理比較特殊,它是經過真實角色找到代理角色,咱們仍是修改一下上面的例子的代理類:

public class GamePlayer implements IGame {
    private String name;
    private IGame proxy = null;
    public GamePlayer(String name){
        this.name = name;

    }

    public IGame getProxy() {
      this.proxy = new GamePlayerProxy(this);
      return this.proxy;
    }

    @Override
    public void attack() {
        if (this.getProxy()!=null){
            System.out.println(name+"正在"+"攻擊");  
        }else {
            System.out.println("請指定代理");
        }

    }

    @Override
    public void move() {
        if (this.getProxy()!=null) {
            System.out.println(name + "正在" + "行走");
        }else {
            System.out.println("請指定代理");
        }

    }

    @Override
    public void dead() {
        if (this.getProxy()!=null) {
            System.out.println(name + "已經" + "死亡");
        }else {
            System.out.println("請指定代理");
        }

    }

    @Override
    public void update() {
        if (this.getProxy()!=null) {
            System.out.println(name + "已經" + "升級");
        }else {
            System.out.println("請指定代理");
        }

    }
    private boolean isProxy(){
        if (this.proxy == null){
            return false;
        }else {
            return  true;
        }
    }
}複製代碼

增長一個私有方法,檢查是否有指定的代理。經過這個方式你能夠看出,你想繞過代理直接訪問真實的類,可是,真實類,仍是給你返回代理。咱們訪問以下:

public class Main {
    public static void main(String[] args) {

        IGame player = new GamePlayer("deep");
        player.move();
        player.attack();
        player.update();
        player.dead();

    }
}複製代碼

總結

代理模式跟中介者模式容易搞混,以後的文章咱們會再介紹一下中介者模式,並進行一下對比。

相關文章
相關標籤/搜索