【设计模式Android】代理模式

设计模式Android 其他相关文章:
【设计模式Android】设计模式六大原则

定义:为其他对象提供一种代理以控制这个对象的访问

代理模式中的角色

Subject抽象主题

抽象主题可以是一个抽象类也可以是一个接口。

public interface  Subject{
    public void doSomeThing();
}

RealSubject具体实例

被代理的角色,是逻辑的具体执行者。

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

代理类

用来代理实际类执行逻辑

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

举个例子

在这里我们举这样一个例子。
比如我们在玩游戏的时候希望找个代练,代替我们升级打怪。这个这个代练就可以认为是一个代理。
我们可以简单写一下做个对比:

Subject抽象主题类

我们在这里定义一下游戏玩家的抽象行为:

public interface IGame {
     public void attack();
    public void move();
    public void dead();
    public void update();
}

RealSubject真是主题类

在这里我们定义下玩家的实际行为:

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();

    }
}

总结

代理模式跟中介者模式容易搞混,之后的文章我们会再介绍一下中介者模式,并进行一下对比。

    原文作者:mymdeep
    原文地址: https://www.jianshu.com/p/1c9422d0b2c2
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞