相信大多数年轻人都喜欢玩游戏。当然笔者也不例外,曾经还有一段时间玩游戏玩到废寝忘食呀。可惜,终究是手残党,游戏怎么都玩不厉害。正是玩游戏的人很多,所以就出现了代练这个职业,把游戏交给代练的人,就能轻松的把游戏玩到一个更高的阶段。这是生活中的一种代理。
而在程序设计中,我们就与生活相结合,来用代练描述一下程序设计中的代理模式。
UML图:

首先,先创建一个接口,这个接口代表着所有的玩家共有的操作:

public interface Player {//玩游戏void play();//游戏结束void over();
}

接着找一位Mike的玩家来实现这个接口:

public class Mike implements Player{@Overridepublic void play() {System.out.println("Mike 激烈战斗中...");}@Overridepublic void over() {System.out.println("Mike 游戏结束");}
}

此时,Mike已经能玩游戏和结束游戏了,可是他怎么都玩不好,于是就找了一位代练,这个代练当然也是一位玩家:

public class LevelingProxy implements Player{//玩家private Player mPlayer;public LevelingProxy(Player player) {mPlayer = player;}//代练玩游戏@Overridepublic void play() {mPlayer.play();}//代练结束游戏@Overridepublic void over() {mPlayer.over();}
}

好的,代练也找好了,是时候开始游戏了,我们创建一游戏客户端的类:

public class Client {public static void main(String[] args) {//创建一个玩家Player player = new Mike();//创建一个代练LevelingProxy proxy = new LevelingProxy(player);proxy.play();proxy.over();}
}

运行一下程序,就会出现结果:

Mike 激烈战斗中…
Mike 游戏结束

虽然说是代练在玩游戏,但这确实Mike的账号在战斗。这就是所谓的代理模式了。我们可以发散思维,代练也可以帮多个玩家代打,我们只需在客户端的类创建玩家,让代理去做就行了。

代理模式在Android中的应用

说到代理,就想起了之前的一篇关于Android IPC机制的博文(详戳http://blog.csdn.net/u010429311/article/details/52300794),里面分析了AIDL的通信机制。其中,有一个自动生成的aidl文件中则用到了代理模式:

/** This file is auto-generated.  DO NOT MODIFY.*/
package com.ipc;public interface IStuManager extends android.os.IInterface {//Stub是一个Binderpublic static abstract class Stub extends android.os.Binder implements com.ipc.IStuManager {//Binder标识private static final java.lang.String DESCRIPTOR = "com.ipc.IStuManager";public Stub() {this.attachInterface(this, DESCRIPTOR);}/*** 将服务器端的Binder对象转换为客户端所需的AIDL对象。如果服务器和客户端同一进程,则返回服务端本身,否则返回Stu.proxy对象*/public static com.ipc.IStuManager asInterface(android.os.IBinder obj) {if ((obj == null)) {return null;}android.os.IInterface iin = obj.queryLocalInterface(DESCRIPTOR);if (((iin != null) && (iin instanceof com.ipc.IStuManager))) {return ((com.ipc.IStuManager) iin);}return new com.ipc.IStuManager.Stub.Proxy(obj);}//返回当前的Binder对象@Overridepublic android.os.IBinder asBinder() {return this;}   /***如果服务端和客户端不同进程,会调用这个方法,通过Stub的内部代理类Proxy完成*@params code 确定调用的方法 data 调用方法的参数 reply 如果目标方法有返回值,则存进reply*/@Overridepublic boolean onTransact(int code, android.os.Parcel data, android.os.Parcel reply, int flags) throws android.os.RemoteException {//省略代码}//内部代理类,两个方法在此类内部实现private static class Proxy implements com.ipc.IStuManager {//服务端Binderprivate android.os.IBinder mRemote;Proxy(android.os.IBinder remote) {mRemote = remote;}@Overridepublic android.os.IBinder asBinder() {return mRemote;}public java.lang.String getInterfaceDescriptor() {return DESCRIPTOR;}//获取列表@Overridepublic java.util.List<com.ipc.Student> getStudentList() throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();java.util.List<com.ipc.Student> _result;try {//将参数写入data,用于调用目标方法,并挂起当前线程_data.writeInterfaceToken(DESCRIPTOR);//跨进程,调用transact方法mRemote.transact(Stub.TRANSACTION_getStudentList, _data, _reply, 0);_reply.readException();//取出结果,作为返回值,继续当前线程_result = _reply.createTypedArrayList(com.ipc.Student.CREATOR);} finally {_reply.recycle();_data.recycle();}return _result;}//添加学生,原理同上@Overridepublic void addStudent(com.ipc.Student stu) throws android.os.RemoteException {android.os.Parcel _data = android.os.Parcel.obtain();android.os.Parcel _reply = android.os.Parcel.obtain();try {_data.writeInterfaceToken(DESCRIPTOR);if ((stu != null)) {_data.writeInt(1);stu.writeToParcel(_data, 0);} else {_data.writeInt(0);}mRemote.transact(Stub.TRANSACTION_addStudent, _data, _reply, 0);_reply.readException();} finally {_reply.recycle();_data.recycle();}}}//标识目标方法的固定数值static final int TRANSACTION_basicTypes = (android.os.IBinder.FIRST_CALL_TRANSACTION + 0);static final int TRANSACTION_getStudentList = (android.os.IBinder.FIRST_CALL_TRANSACTION + 1);static final int TRANSACTION_addStudent = (android.os.IBinder.FIRST_CALL_TRANSACTION + 2);}
}

通过上述代码可以看到,Proxy是一个代理类,代表着服务端的Binder,通过代理模式调用了Binder的transact方法,在Android的ServiceManager等其他地方也存在用代理模式来实现的实例。那用代理模式来实现有什么优势呢?

优缺点

1.优点

  • 职责清晰
    真实的角色就是实现实际的业务逻辑,不用关心其他非本职责的事务,通过后期的代理完成一件完成事务,附带的结果就是编程简洁清晰。
  • 中介作用
    代理对象可以在客户端和目标对象之间起到中介的作用,这样起到了中介的作用和保护了目标对象的作用。
  • 高扩展性
    使用代理模式可以很容易地进行扩展,添加种类。

2.缺点
     代理模式倒是没有什么缺点,要说有,大概就是设计模式的通病:类多了,会显得复杂。

代理模式——游戏代练相关推荐

  1. 《大话设计模式(C#实现)》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+设计模式+GoF+UML+单例模式+观察者模式+抽象工厂+代理模式+框架编程+立钻哥哥++OK+)

    <大话设计模式(C#实现)> 版本 作者 参与者 完成日期 备注 YanlzFramework_GoF_V01_1.0 严立钻 2020.02.10 ##<大话设计模式(C#实现)& ...

  2. 设计模式之代理模式(Proxy Pattern)

    定义:为其他对象提供一种代理以控制这个对象的访问,也叫做委托模式. 咱们比作游戏,通俗讲代理模式就是,一个主题虚基类派生出两个子类,一个玩家类,实现相关操作,一个是代练类,代替执行玩家相关操作,代练类 ...

  3. 23种设计模式----------代理模式(一)

    代理模式也叫委托模式. 代理模式定义:对其他对象提供一种代理从而控制对这个对象的访问.就是,代理类 代理 被代理类,来执行被代理类里的方法. 一般情况下,代理模式化有三个角色. 1,抽象的主题类(或者 ...

  4. 设计模式之禅【代理模式】

    真刀实枪之代理模式 我是游戏至尊 "最近几年王者荣耀的热度飙升,自己打时可以体验到其中的升级乐趣,但是时间过得很快啊!自己不想打,找代练,好主意!" 作为一名程序员,先将打游戏这段 ...

  5. Proxy_代理模式

    代理模式(Proxy) 代理模式有点像老大和小弟,也有点像分销商.主要解决的是问题是为某些资源的访问.对象的类的易用操作上提供方便使用的代理服务.而这种设计思想的模式经常会出现在我们的系统中,或者你用 ...

  6. 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式

    1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...

  7. [设计模式] - 代理模式(静态代理与动态代理)

    文章目录 一.代理模式简介 1. 什么是代理模式 2. 简单举例 二.代理模式的设计思路 1. 代理模式的构成 1. 静态代理 2. 动态代理 (1)接口代理 (2)Cglib代理 三. 代理模式总结 ...

  8. Java设计模式——代理模式

    文章目录 1.简介 2.推荐实现案例 3.优缺点 3.1 优点 3.2 缺点 4.应用场景 5.注意事项 6.拓展 6.1 普通代理 6.2 强制代理 6.3 代理类的个性 6.4 动态代理 7.最佳 ...

  9. 【C++设计模式】-03代理模式

    代理模式 代理模式介绍 今天继续学习设计模式,今天我们来学习代理模式.其实这个模式呢在我们的生活早已经运用起来了.笔者看到这个模式就联想到了代理商.我们客户买东西一般都是经过代理商的,代理商和真正的生 ...

最新文章

  1. shell按行读取文件的常见几种方法
  2. jQuery获取CSS样式中的颜色值的问题,不同浏览器格式不同怎么办
  3. Java如何实现二维码?【附源码】
  4. bzoj 2435: [Noi2011]道路修建 树上 dp
  5. think in uml-关系
  6. Nacos配置的优先级
  7. typescript_如何掌握高级TypeScript模式
  8. SAP License:外购和自产货物视同销售业务理解
  9. Visual C++ 2008入门经典 第十章标准模板库(二)
  10. recyclervie刷新到底部_自定义RecyclerView添加HeaderView,添加FooterView,实现滑动到底部,加载更多...
  11. Deepin使用苹果主题
  12. 计算机二级vb语言题库百度云,[计算机二级vb题库]计算机二级VB语言程序设计考试题及答案.doc...
  13. 零基础如何用平面设计排版软件PS进行布局构图
  14. 泛微 E9开发视频教程
  15. 学习日记-wps表格 工资条的制作
  16. ckplayer超酷网页播放器
  17. DDD领域建模基本流程
  18. js 调用谷歌插件截图跨域的iframe---FireShot
  19. cesium显示帧率FPS控件
  20. 三星Galaxy之父加盟网秦,网秦安全能否脱胎换骨?

热门文章

  1. eclipse c++安装
  2. react学习—高阶组件HOC
  3. 詹姆斯高斯林_詹姆斯·高斯林(James Gosling)加入RCDb顾问委员会
  4. C++ 取json中的某一个值,解析json字符串
  5. 基于ZigBee的WPAN网络配置应用
  6. php充值赠送如何结算,餐饮会员充值赠送怎么计算成本?
  7. RedHat9.0红帽子LIUNX
  8. Android 疑难杂症
  9. 结合stata和pyecharts对双11淘宝销量数据分析(进度5%,咯咯咯 我鸽了)
  10. (超详细的新手教程)怎么下载JDK包?