代理模式——游戏代练
相信大多数年轻人都喜欢玩游戏。当然笔者也不例外,曾经还有一段时间玩游戏玩到废寝忘食呀。可惜,终究是手残党,游戏怎么都玩不厉害。正是玩游戏的人很多,所以就出现了代练这个职业,把游戏交给代练的人,就能轻松的把游戏玩到一个更高的阶段。这是生活中的一种代理。
而在程序设计中,我们就与生活相结合,来用代练描述一下程序设计中的代理模式。
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.缺点
代理模式倒是没有什么缺点,要说有,大概就是设计模式的通病:类多了,会显得复杂。
代理模式——游戏代练相关推荐
- 《大话设计模式(C#实现)》(Yanlz+VR云游戏+Unity+SteamVR+云技术+5G+AI+设计模式+GoF+UML+单例模式+观察者模式+抽象工厂+代理模式+框架编程+立钻哥哥++OK+)
<大话设计模式(C#实现)> 版本 作者 参与者 完成日期 备注 YanlzFramework_GoF_V01_1.0 严立钻 2020.02.10 ##<大话设计模式(C#实现)& ...
- 设计模式之代理模式(Proxy Pattern)
定义:为其他对象提供一种代理以控制这个对象的访问,也叫做委托模式. 咱们比作游戏,通俗讲代理模式就是,一个主题虚基类派生出两个子类,一个玩家类,实现相关操作,一个是代练类,代替执行玩家相关操作,代练类 ...
- 23种设计模式----------代理模式(一)
代理模式也叫委托模式. 代理模式定义:对其他对象提供一种代理从而控制对这个对象的访问.就是,代理类 代理 被代理类,来执行被代理类里的方法. 一般情况下,代理模式化有三个角色. 1,抽象的主题类(或者 ...
- 设计模式之禅【代理模式】
真刀实枪之代理模式 我是游戏至尊 "最近几年王者荣耀的热度飙升,自己打时可以体验到其中的升级乐趣,但是时间过得很快啊!自己不想打,找代练,好主意!" 作为一名程序员,先将打游戏这段 ...
- Proxy_代理模式
代理模式(Proxy) 代理模式有点像老大和小弟,也有点像分销商.主要解决的是问题是为某些资源的访问.对象的类的易用操作上提供方便使用的代理服务.而这种设计思想的模式经常会出现在我们的系统中,或者你用 ...
- 「补课」进行时:设计模式(5)——从 LOL 中学习代理模式
1. 前文汇总 「补课」进行时:设计模式系列 2. 从 LOL 中学习代理模式 我是一个很喜欢玩游戏的人,虽然平时玩游戏的时间并不多,但我也是一个忠实的 LOL 的爱好者,就是段位有点惨不忍睹,常年倔 ...
- [设计模式] - 代理模式(静态代理与动态代理)
文章目录 一.代理模式简介 1. 什么是代理模式 2. 简单举例 二.代理模式的设计思路 1. 代理模式的构成 1. 静态代理 2. 动态代理 (1)接口代理 (2)Cglib代理 三. 代理模式总结 ...
- Java设计模式——代理模式
文章目录 1.简介 2.推荐实现案例 3.优缺点 3.1 优点 3.2 缺点 4.应用场景 5.注意事项 6.拓展 6.1 普通代理 6.2 强制代理 6.3 代理类的个性 6.4 动态代理 7.最佳 ...
- 【C++设计模式】-03代理模式
代理模式 代理模式介绍 今天继续学习设计模式,今天我们来学习代理模式.其实这个模式呢在我们的生活早已经运用起来了.笔者看到这个模式就联想到了代理商.我们客户买东西一般都是经过代理商的,代理商和真正的生 ...
最新文章
- shell按行读取文件的常见几种方法
- jQuery获取CSS样式中的颜色值的问题,不同浏览器格式不同怎么办
- Java如何实现二维码?【附源码】
- bzoj 2435: [Noi2011]道路修建 树上 dp
- think in uml-关系
- Nacos配置的优先级
- typescript_如何掌握高级TypeScript模式
- SAP License:外购和自产货物视同销售业务理解
- Visual C++ 2008入门经典 第十章标准模板库(二)
- recyclervie刷新到底部_自定义RecyclerView添加HeaderView,添加FooterView,实现滑动到底部,加载更多...
- Deepin使用苹果主题
- 计算机二级vb语言题库百度云,[计算机二级vb题库]计算机二级VB语言程序设计考试题及答案.doc...
- 零基础如何用平面设计排版软件PS进行布局构图
- 泛微 E9开发视频教程
- 学习日记-wps表格 工资条的制作
- ckplayer超酷网页播放器
- DDD领域建模基本流程
- js 调用谷歌插件截图跨域的iframe---FireShot
- cesium显示帧率FPS控件
- 三星Galaxy之父加盟网秦,网秦安全能否脱胎换骨?
热门文章
- eclipse c++安装
- react学习—高阶组件HOC
- 詹姆斯高斯林_詹姆斯·高斯林(James Gosling)加入RCDb顾问委员会
- C++ 取json中的某一个值,解析json字符串
- 基于ZigBee的WPAN网络配置应用
- php充值赠送如何结算,餐饮会员充值赠送怎么计算成本?
- RedHat9.0红帽子LIUNX
- Android 疑难杂症
- 结合stata和pyecharts对双11淘宝销量数据分析(进度5%,咯咯咯 我鸽了)
- (超详细的新手教程)怎么下载JDK包?