原文地址: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设计之功能模块的代理模式的更多相关文章

  1. php 23种设计模型 - 代理模式

    代理模式(Proxy) 在代理模式(Proxy Pattern)中,一个类代表另一个类的功能.这种类型的设计模式属于结构型模式. 在代理模式中,我们创建具有现有对象的对象,以便向外界提供功能接口. 介 ...

  2. JAVA设计模式(09):结构型-代理模式(Proxy)

    代理模式是经常使用的结构型设计模式之中的一个,当无法直接訪问某个对象或訪问某个对象存在困难时能够通过一个代理对象来间接訪问,为了保证client使用的透明性,所訪问的真实对象与代理对象须要实现同样的接 ...

  3. C#设计模式之代理模式(二)

    15.3 代理模式应用实例 下面通过一个应用实例来进一步学习和理解代理模式.        1. 实例说明        某软件公司承接了某信息咨询公司的收费商务信息查询系统的开发任务,该系统的基本需 ...

  4. 设计模式(十三):从“FQ”中来认识代理模式(Proxy Pattern)

    我们知道Google早就被墙了,所以FQ才能访问Google呢,这个“FQ”的过程就是一个代理的过程.“代理模式”在之前的博客中不止一次的提及过,之前的委托回调就是代理模式的具体应用.今天我们就从“F ...

  5. Java中的代理模式

    代理模式在Java Web的框架中经常使用到.比如说在对数据库的访问中,核心功能是对数据库的增删改查,而连接数据库.处理事务等功能我们在开发中也要考虑到.所以我们将数据库的CRUD抽象到接口中,然后实 ...

  6. javascript设计模式与开发实践阅读笔记(6)——代理模式

    代理模式:是为一个对象提供一个代用品或占位符,以便控制对它的访问. 代理模式的关键是,当客户不方便直接访问一个对象或者不满足需要的时候,提供一个替身对象来控制对这个对象的访问,客户实际上访问的是替身对 ...

  7. 【Java千问】你了解代理模式吗?

    代理模式详解 1 什么是代理模式? 一句话描述:代理模式是一种使用代理对象来执行目标对象的方法并在代理对象中增强目标对象方法的一种设计模式. 详细描述: 1.理论基础-代理模式是设计原则中的“开闭原则 ...

  8. 设计模式:代理模式是什么,Spring AOP还和它有关系?

    接着学习设计模式系列,今天讲解的是代理模式. 定义 什么是代理模式? 代理模式,也叫委托模式,其定义是给某一个对象提供一个代理对象,并由代理对象控制对原对象的引用.它包含了三个角色: Subject: ...

  9. javascript设计模式实践之代理模式--图片预加载

    图片的预加载就是在加载大图片前,先显示一个loading.gif,就算在网络比较慢的时候也能让人知道正在加载,总比啥反应都没有强. 下面这段代码就是预加载的一个简单的实现,假设先不处理加载图片时的on ...

随机推荐

  1. Html+css 练习写页面发现的错误及解决办法。

    最近开始模仿写一些静态页面,今天模仿的是中华咨询网.写了一个简单的js(功能:当鼠标hover一级菜单的时候,设置二级菜单为显示,当鼠标hover二级菜单的选项时候,二级菜单不收回.当鼠标移出菜单一级 ...

  2. [ShareSDK for Android]新浪微博常见问题

    一.新浪sso授权报错sso package or sign error 1. 新浪微博开放平台应用没有审核通过,不能用sso登陆,否则报错.关闭sso登陆Platform platform = Sh ...

  3. HTML5手机APP开发入(4)

    HTML5手机APP开发入(4) 课程内容 完成一个自定义的Component用来展现通讯录用户的明细信息如下图 http://bootsnipp.com/snippets/featured/prof ...

  4. Lucene 4.X 倒排索引原理与实现: (3) Term Dictionary和Index文件 (FST详细解析)

    我们来看最复杂的部分,就是Term Dictionary和Term Index文件,Term Dictionary文件的后缀名为tim,Term Index文件的后缀名是tip,格式如图所示. Ter ...

  5. 导出Redis某个列表所有数据的语句

     echo "smembers done:www.huaihua.gov.cn" | redis-cli -h 127.0.0.1  >> /home/dz/fkw.d ...

  6. IDE、SATA、SCSI、SAS、FC、SSD硬盘类型介绍[zz]

    目前所能见到的硬盘接口类型主要有IDE.SATA.SCSI.SAS.FC等等. IDE是俗称的并口,SATA是俗称的串口,这两种硬盘是个人电脑和低端服务器常见的硬盘.SCSI是"小型计算机系 ...

  7. Make it run, make it right, make it fast

    如果问我工作十多年后相比刚毕业参加的时候,学到了哪些重要的经验,那么"Make it work, make it right, make it fast"一定是其中最重要的经验之一 ...

  8. Generating a new ASP.NET session in the current HTTPContext

    void regenerateId() { System.Web.SessionState.SessionIDManager manager = new System.Web.SessionState ...

  9. 少睡与吸烟影响IQ

        导读:据英国<每日邮报>报道,根据科学家一项最新研究发现,一晚的糟糕睡眠,对大脑可能产生很大损害,就等同头部遭到了一次严重的撞击.长期睡眠不好会造成智力下降,请看[科学探索]揭秘: ...

  10. Hadoop - 实时查询Drill

    1.概述 在现实业务当中,存在这样的业务场景,需要实时去查询HDFS上的相关存储数据,普通的查询(如:Hive查询),时延较高.那么,是否存在时延较小的查询组件.在业界目前较为成熟的有Cloudera ...