Android 代理模式

<<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:后边会分析强制代理...

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 226,097评论 6 523
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 97,198评论 3 410
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 173,602评论 0 370
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 61,750评论 1 304
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 70,684评论 6 404
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 54,151评论 1 317
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 42,349评论 3 433
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 41,430评论 0 282
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 47,986评论 1 328
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 39,969评论 3 351
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 42,071评论 1 359
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 37,667评论 5 352
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 43,358评论 3 342
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 33,757评论 0 25
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 34,944评论 1 278
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 50,684评论 3 384
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 47,123评论 2 368

推荐阅读更多精彩内容

  • 设计模式Android 其他相关文章:【设计模式Android】设计模式六大原则 定义:为其他对象提供一种代理以控...
    mymdeep阅读 2,901评论 0 16
  • 此篇文章说是通过代理模式来实现简单的AOP其实只是顺带的,主要目的还是讲一下代理模式,在Android中使用的代理...
    C6C阅读 1,707评论 2 9
  • 代理模式是什么 如上图所示,代理代表着另一终端中的某个真实服务对象,Client 调用代理(Client help...
    野生西瓜阅读 2,324评论 2 14
  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 172,528评论 25 707
  • 庸碌兀兀已穷年彷徨不能前回首终知悔才知覆来难 凉青丝愁断伤白发风霜残朽凋年华昨夜凉雨安未安?落红成忧怅然下
    梦破寒凉阅读 211评论 2 3