webgame设计之功能模块的代理模式
原文地址:http://chengduyi.com/blog/?post=27
在游戏设计中,通常会将一些实现了具体功能的模块进行封装,达到重用的目的。这些功能模块包括:1、网络通信模块(实现连接,断开,消息发送、接收,错误等处理);2、资源加载管理模块(实现资源加载,缓存,进度通知,分类型加载、管理等)。
设计实现这些功能模块的方法很多,设计过程中最好做到使这些模块在外部启动简单、使用方便、重用容易。
我在设计中使用了代理模式的思想,就是将封装的功能留出一个代理类供外部继承实现。使用时候的具体步骤是:1、重写该代理类;2、实例化重写的代理类,并将该对象设置到管理器中;3、创建消息的逻辑处理类对象,并使用方法setDelegate设置映射;4、访问该代理类对象实现操作。
注意地方有:重写的代理类最好是单例的,方便调用。步骤2是在游戏启动的时候完成。步骤3里消息的逻辑处理类可能是很多个,最好也是单例的,方便调用,该步骤最好在步骤2中代理类的构造函数里调用完成。
现在来模拟设计一个网络通信模块,整个功能比较简单,定义了两个类(NetManager、NetProxy)和一个接口(INetDelegate),其中NetManager和NetProxy存在对象共享,必须在一个包内。
INetDelegate接口的伪代码:
/** 定义网络数据处理逻辑接 */
interface INetDelegate public function receive(data:ByteArray):void;
NetManager类的伪代码:
/** 单例的,外部只能设置一次该类的只写属性netProxy */
class NetManager /** 将socket封装,外部不可直接访问 */
private var socket:Socket; /** 通过只设置一次实现系统初始化管理 */
private var _netProxy:NetProxy;
public function set netProxy(proxy:NetProxy):void{
if(_netProxy){
//报错处理,只能设置一次该代理
}else{
_netProxy = proxy;
//与同包的NetProxy共享该属性
_netProxy.socket = socket;
}
} /** 在构造函数中创建好socket对象后调用 */
private function configureListeners():void {
socket.addEventListener(Event.CLOSE, closeHandler);
socket.addEventListener(Event.CONNECT, connectHandler);
socket.addEventListener(IOErrorEvent.IO_ERROR,
ioErrorHandler);
socket.addEventListener(SecurityErrorEvent.SECURITY_ERROR,
securityErrorHandler);
socket.addEventListener(ProgressEvent.SOCKET_DATA,
socketDataHandler);
} private function closeHandler(event:Event):void {
_netProxy.onClose();//移交处理权
} private function connectHandler(event:Event):void {
_netProxy.onConnect();//移交处理权
} private function ioErrorHandler(event:IOErrorEvent):void {
_netProxy.onError(IOErrorEvent.IO_ERROR);//移交处理权
} private function securityErrorHandler(event:SecurityErrorEvent):void {
//移交处理权
_netProxy.onError(SecurityErrorEvent.SECURITY_ERROR);
} private function socketDataHandler(event:ProgressEvent):void {
//TODO:处理断包、连包,读取消息长度,如果剩余长度够数据包,
//读取一个数据包到data里,继续执行,否则返回。
_netProxy.receive(data);//移交处理权
}
NetProxy类的伪代码:
/**
* 不是单例的,外部通过继承该类实现功能,外部继承类最好是单例的
* 并将他设置给NetManager的netProxy属性。
*/
class NetProxy /**
* 不会直接创建,在设置给NetManager时让NetManager共享出来
* 且包内封装,外部不能直接访问网络实体对象
*/
internal var socket:Socket; /**
* 消息处理逻辑类的字典
* 将消息头与逻辑类对应
* 逻辑类必须实现接口INetDelegate
*/
private var dictDelegate = new Dictionary(); final public function open(host:String, port:int){
socket.connect(host, port):
} final public function close():void{
socket.close();
} public function onError(errorType:String):void{
//外部继承类重写该方法实现
} public function onOpen():void{
//外部继承类重写该方法实现
} public function onClose():void{
//外部继承类重写该方法实现
} internal function receive(data:ByteArray):void{
//TODO:读取消息头
//分发到dictDelegate中对应的
//逻辑类(INetDelegate)的receive方法处理
} final public function send(head:uint, body:ByteArray):void{
//TODO:构建消息,发送
//虽然可以在能获得实例的任何地方调用
//但最好在INetDelegate的实现类中调用,达到逻辑封装
} final protected function setDelegate(head:uint,
delegate:INetDelegate):void{
//TODO:在dictDelegate中添加映射
//相同head只能一个处理逻辑类,重复设置报错
//最好在外部继承类的构造函数中调用,做到网络功能模块启动时
//就设置好了处理映射
}
netcontrol.rar 8.39KB
webgame设计之功能模块的代理模式的更多相关文章
- php 23种设计模型 - 代理模式
代理模式(Proxy) 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 介 ...
- JAVA设计模式(09):结构型-代理模式(Proxy)
代理模式是经常使用的结构型设计模式之中的一个,当无法直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性,所訪问的真实对象与代理对象须要实现同样的接 ...
- C#设计模式之代理模式(二)
15.3 代理模式应用实例 下面通过一个应用实例来进一步学习和理解代理模式. 1. 实例说明 某软件公司承接了某信息咨询公司的收费商务信息查询系统的开发任务,该系统的基本需 ...
- 设计模式(十三):从“FQ”中来认识代理模式(Proxy Pattern)
我们知道Google早就被墙了,所以FQ才能访问Google呢,这个“FQ”的过程就是一个代理的过程.“代理模式”在之前的博客中不止一次的提及过,之前的委托回调就是代理模式的具体应用.今天我们就从“F ...
- Java中的代理模式
代理模式在Java Web的框架中经常使用到.比如说在对数据库的访问中,核心功能是对数据库的增删改查,而连接数据库.处理事务等功能我们在开发中也要考虑到.所以我们将数据库的CRUD抽象到接口中,然后实 ...
- javascript设计模式与开发实践阅读笔记(6)——代理模式
代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...
- 【Java千问】你了解代理模式吗?
代理模式详解 1 什么是代理模式? 一句话描述:代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式. 详细描述: 1.理论基础-代理模式是设计原则中的“开闭原则 ...
- 设计模式:代理模式是什么,Spring AOP还和它有关系?
接着学习设计模式系列,今天讲解的是代理模式. 定义 什么是代理模式? 代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用.它包含了三个角色: Subject: ...
- javascript设计模式实践之代理模式--图片预加载
图片的预加载就是在加载大图片前,先显示一个loading.gif,就算在网络比较慢的时候也能让人知道正在加载,总比啥反应都没有强. 下面这段代码就是预加载的一个简单的实现,假设先不处理加载图片时的on ...
随机推荐
- Leetcode 27 Remove Element STL
和remove zero类似的方法完成该题 class Solution { public: int removeElement(vector<int>& nums, int va ...
- Spark安装指南
一.Windows环境安装Spark 1.安装Java环境:jdk-8u101-windows-x64 配置环境变量: (1)增加变量名:JAVA_HOME 变量值:C:\Program File ...
- JavaScript中如何中断forEach循环
先来看下forEach的实现 // Production steps of ECMA-262, Edition 5, 15.4.4.18// Reference: http://es5.github. ...
- Javascript:常用函数封装
//cookie function setCookie(name, value, iDay) { if(iDay!==false) { var oDate=new Date(); oDate.setD ...
- 【Android】Android 移动应用数据到SD
[Android]Android 移动应用数据到SD 在应用的menifest文件中指定就可以了,在 <manifest> 元素中包含android:installLocation 属性, ...
- Crypto++入门学习笔记(DES、AES、RSA、SHA-256)(加解密)
转自http://www.cppblog.com/ArthasLee/archive/2010/12/01/135186.html 最近,基于某些原因和需要,笔者需要去了解一下Crypto++库,然后 ...
- Hadoop - Mac OSX下配置和启动hadoop以及常见错误解决
0. 安装JDK 参考网上教程在OSX下安装jdk 1. 下载及安装hadoop a) 下载地址: http://hadoop.apache.org b) 配置ssh环境 在terminal里面输入: ...
- ubuntu下matplotlib画图中文乱码问题
最近因为论文原因在学习机器学习,看的一本叫做<机器学习实战>的书,看了看还是不错的,因为其中既有原理又有实例.今天载使用matplotlib进行画图时,发现中文会显示为小方块,这个问题真是 ...
- 前端开发者进阶之ECMAScript新特性【一】--Object.create
Object.create(prototype, descriptors) :创建一个具有指定原型且可选择性地包含指定属性的对象 参数:prototype 必需. 要用作原型的对象. 可以为 nul ...
- Cocos2dx使用wxsqlite开源加密SQLite3数据库
最近使用wxsqlite加密sqlite3数据库,刚开始折腾好几天,在xcode上一直编译不通过,后来在sqlite3.c找到配置,编译顺利通过,太激动了,哈哈,废话少说!总结一下android和io ...