美文网首页
Android 代理模式

Android 代理模式

作者: 哎呀啊噢 | 来源:发表于2018-08-17 17:29 被阅读7次

    <<1.0 普通代理>>

    前言:通过打游戏的例子来分析普通代理模式的原理,打游戏的过程无非就是打怪升级,那么把这一过程系统化,如图所示:


    微信截图_20180817172314.png

    代码清单-游戏者接口

    public interface IGamePlayer {
      
      //登陆游戏
      public void login(String user,String password);
      
      //打怪,游戏主要乐趣
      public void killBoss();
      
      //升级
      public void upgrade();
      
    }
    
    

    定义了游戏的三个简单方法分别是:登录游戏、打怪、升级;

    代码清单-游戏者

    public class GamePlayer implements IGamePlayer {
      private String name;
    
      //构造函数传递玩家名称
      public GamePlayer(String _name) {
        this.name = _name;
      }
    
      @Override
      public void login(String user, String password) {
        System.out.print("登录用户名:" + user + "的用户" + this.name + "succes");
      }
    
      @Override
      public void killBoss() {
        System.out.print(this.name+"在打怪...");
      }
    
      @Override
      public void upgrade() {
        System.out.print(this.name+"又升级了...");
      }
    }
    

    在实现类的构造函数中传递玩家的姓名,方便后期调式,通过这样的场景来模拟游戏的过程代码入下

    代码清单

    public class Client{
    
      public static void main(String[] agrs) {
        IGamePlayer iGamePlayer = new GamePlayer("test");
        //记录开始时间
        System.out.print("开始时间:"+System.currentTimeMillis());
        //登录游戏
        iGamePlayer.login("username","password");
        //打怪
        iGamePlayer.killBoss();
        //升级
        iGamePlayer.upgrade();
        System.out.print("结束时间:"+System.currentTimeMillis());
      }
    }
    
    输出结果:
    开始时间:1534492600636
    登录用户名:username的用户testsucces
    test再打怪...
    test又升级了...
    结束时间:1534492600637
    

    运行结果显示也没有问题,记录了一个游戏的主要流程;心理学家告诉我们,人类对于苦难的记忆比对于喜悦的记忆要深刻,但是人类对于喜悦是“趋利”性的,每个人能都想Happy,都不想苦难靠近,要想获取幸福,苦难也在所难免的,游戏也是如此,打游戏时间长了,腰酸背痛,眼睛干涩,手臂发麻,胡思乱想,从而导致走火入魔。那怎么办?想玩游戏,又不想碰触到游戏的苦难中,如何解决呢?有办法,现在游戏代理的公司特别多,把自己的账号交给代练人员,修改代码...

    微信截图_20180817161154.png

    在类图中添加了一个GamePlayerProxy类来代表玩家代练,它也不能作弊,也得动手打怪升级,所以同样需要实现IGamePlayer接口,代码如下:

    public class GamePlayerProxy implements IGamePlayer {
    
      private IGamePlayer gamePlayer = null;
    
      //通过构造函数传递要对谁进行代练
      public GamePlayerProxy(IGamePlayer _gamePlayer) {
        this.gamePlayer = _gamePlayer;
      }
    
      //代练登录
      @Override
      public void login(String user, String password) {
        this.gamePlayer.login(user, password);
      }
    
      //代练打怪
      @Override
      public void killBoss() {
        this.gamePlayer.killBoss();
      }
    
      //代练升级
      @Override
      public void upgrade() {
        this.gamePlayer.upgrade();
      }
    }
    

    很简单,首先通过构造函数说明为谁代练打游戏,然后通过手动开始代理用户进行打怪升级,场景类Clint如下:

    public class Client {
    
      public static void main(String[] agrs) {
        //定义一个游戏玩家
        IGamePlayer player = new GamePlayer("test");
        //定义一个代练者
        IGamePlayer proxy = new GamePlayerProxy(player);
        //开始打游戏。记录下时间戳
        System.out.print("开始时间:"+System.currentTimeMillis()+"\n");
        //登录
        proxy.login("username" ,"password");
        //开始打怪
        proxy.killBoss();
        //升级
        proxy.upgrade();
        //记录结束时间
        System.out.print("结束时间:"+System.currentTimeMillis());
    
      }
    }
    

    运行结果如下,还是test玩家在打游戏:

    开始时间:1534494690426
    登录用户名:username的用户testsucces
    test再打怪...
    test又升级了...
    结束时间:1534494690426
    

    没有任何改变,但是游戏已经在升级了,有人帮你干活了,惹不起...

    代理模式的定义

    代理模式是一个使用率非常高的模式,定义如下:
    Provide a surrogate or placeholder for another object to control access to it.(为另一个对象提供代理或占位符来控制对它的访问。)

    代理模式也叫委托模式,它是一项基本设计技巧,许多其他模式,如状态模式、策略模式、访问模式本质上是在更特殊的场合采用了委托模式,而且在日常开发中,代理模式可以提供非常好的访问控制;


    微信截图_20180817164723.png

    代理模式通用类图角色定义:

    • Subject抽象主题角色
      抽象主题类可以是抽象类也可以是接口,是一个最普通的业务类型定义,无特殊要求;
    • RealSubject具体主题颜色
      也叫被委托角色,被代理角色,业务逻辑的具体执行者;
    • Proxy代理主题角色
      也叫代理类、委托类,它负责对真实角色的应用,把所有抽象主题类定义的方法限制委托给真实的主题角色实现,并且在真实主题角色处理完毕前后做预处理和善后处理工作。

    Subject抽象主题类通用源码如下:

      public interface Subject{
        //定义一个方法
        public void request();
    
      }
    

    在接口中定义了一个方法request来作为方法的代表,RealSubject对它进行实现,代码如下:

    public class RealSubject implements Subject{
      //实现方法
      @Override
      public void request() {
        //业务逻辑处理
      }
    }
    

    RealSubject是一个正常的业务实现类,代理模式的核心就在代理类上,代码如下

    public class Proxy implements Subject{
      //要代理哪个实现类
      private Subject subject = null;
    
      //默认被代理
      public Proxy(){
        this.subject = new Proxy();
      }
      //通过构造函数传递代理者
      public Proxy(Object...objects){
    
      }
      //实现接口中定义的方法
      @Override
      public void request() {
          this.after();
          this.subject.request();
          this.before();
      }
    
      //预处理
      private void  before(){
        //do something
      }
    
      //善后处理
      private void after(){
        //do something
      }
    
    }
    

    至于before和after方法,是一个引子崭新的模式。
    一个代理类可以代理多个被委托者或者被代理者,因此一个代理者具体代理哪个真实的主题角色,是由场景类决定的。当然最简单的情况就是一个主题类和一个代理类,这就是最简单的代理模式。

    代理模式的优点

    • 职责清晰
      真实的角色就是实现具体的业务逻辑,不用关心其他非本职的事务。

    • 高扩展
      具体主题角色是随时发生变化的,只要实现了接口,代理类可以不做任何修改使用;

    • 智能化
      主要体现在动态代理上;

      ps:后边会分析强制代理...

    相关文章

      网友评论

          本文标题:Android 代理模式

          本文链接:https://www.haomeiwen.com/subject/dpftiftx.html