JiveJdon Community Forums
在线313人   首页   主题表   培训咨询   标签   精华   查搜   注册    登陆 RSS
首页 » 论坛 » 设计模式、框架和架构
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表
???en_US.forumThreadNext.name??? 下一主题
1 2 Go 总共有 15 回复 / 2
 发表新帖子   回复该主题贴
zard222

悄悄话
发表文章: 7
注册时间: 2003年12月16日 13:27
请教一下,该如何重构或设计才好?? 2004年02月06日 14:16 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
标签列表 设计模式(165)     
我自己在做一个网络文字游戏的东西,其中遇到这样一个问题,该如何重构或设计??请教各位高手:

首先,客户端发送一个command,服务器端由cammand模式调用服务器端的player类的行为函数,比如:a.talkto(),在talkto()函数中查找到你要交谈的对象是b,那么调用b.talkedBy(this);,然后在talkedBy()中查找a和b之间可以通过交谈激活的任务(task),然后调用task.talk(a);在task.talk()中查找到当前用户要完成的事件(一个任务由多个事件组成),调用event.talk(a),在event.talk()中判断用户有没有达到完成的要求,然后返回true或false;

我觉得这样一个调一个很是不好,并且再添加一个giveto()行为又要添加一串,应该怎么重构或设计才好???
jrog

悄悄话
发表文章: 51
注册时间: 2004年02月03日 17:01
Re: 请教一下,该如何重构或设计才好?? 2004年02月06日 14:37 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
你可不可以贴一个sequence diagram或者是collaboration diagram出来呀?这样绕来绕去都不明白你想实现什么!呵呵
ajoo

悄悄话
发表文章: 64
注册时间: 2004年01月09日 07:39
Re: 请教一下,该如何重构或设计才好?? 2004年02月06日 16:21 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
呵呵,类似一个mud游戏是吗?
这样:

interface Object{
void accept(ObjectVisitor v);
}
interface Player extends Object{......}
interface ObjectVisitor{
void visitPlayer(Player p);
void visitNPC(NPC npc);
......
}
interface Action{
void accept(ActionVisitor v);
}
interface ActionVisitor{
void visitTalk(Player p, Object target);
void visitGive(Player p, Object target);
......//all other actions
}
class GameEngine implements ActionVisitor, GameState{
public void visitTalk(Player p, Object target){
try{
final Task t = findTaskForTalk(p, target);
for(Event event: t.getEvents()){
if(!event.complete(this, p)){
failEvent(p, event);
}
}
succeedTask(p, t);
}
catch(NoTaskException e){}
}
public void visitGive(Player p, Object target){
......
}
...
}

主循环接受玩家发来的消息,解释成一个一个的Action,然后发给GameEngine对象。(很可能是通过一个单独的线程来做。你可能要考虑用线程池哦,至少要先预留一个接口)
GameEngine对象包含所有的游戏逻辑。每一个动作所引发的相关动作和游戏状态变化都被封装在里面。它可以通过一个player的id找到player的socket从而给客户发送相关的信息。
另外,GameEngine也负责储存游戏状态,比如通过一些check point来储存。
GameEngine也必须是线程安全的。

所有的玩家所能发出的动作都由一个Action来代表。GameEngine通过ActionVisitor来区分不同的action。
游戏中所有的实体,包括物品,npc,wizard, player,都是一个Object。(这个Object不是java.lang.Object)
每个Player对象包含这个player的id等信息。GameEngine可以通过这个id找到所有关于这个player的状态。
每个event都设有一定的完成条件。event通过判断GameState的状态和Player的状态来决定是否符合条件。


这样,应该就差不多了。give和talk不过是两种不同的action。理论上,系统里可以存在任意多的action。


这里面,麻烦的,应该就是各个event的规则编写。简单的就是硬编码。如果要搞得好一些,只怕就要实现一个script来做这个事情。

zard222

悄悄话
发表文章: 7
注册时间: 2003年12月16日 13:27
Re: 请教一下,该如何重构或设计才好?? 2004年02月06日 16:58 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
多谢ajoo,我就是做一个mud游戏,游戏中所有的东西,包括任务事件,npc,地图,所有一切元素都是通过数据库定义的,npc,goods, player,map,都有一个package,走题了。。。,我的系统中用户的action是由command模式解析,顺序图:
ajoo

悄悄话
发表文章: 64
注册时间: 2004年01月09日 07:39
Re: 请教一下,该如何重构或设计才好?? 2004年02月07日 00:30 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Command最好不要直接调用Player.talkTo(NPC).
我之所以推荐visitor,是因为在visitor里面,你的Action什么也不干,只是负责描述这个action。比如:“ajoo跟椅子说'对不起'”, 或者“ajoo高举烤鸡腿对着鸡屁股当头砸了下来”之类的。

至于如何解释执行这些action,应该交给一个单独的visitor模块。
这样,给出不同的visitor模块,你可以实现完全不同的逻辑。

而且,talk就只能talk to NPC吗?不能talk to Player?

其它的先不说了,不是很清楚你的系统的需求,所以也不好说。
banq

悄悄话
发表文章: 9484
注册时间: 2002年08月03日 17:08
Re: 请教一下,该如何重构或设计才好?? 2004年02月07日 11:07 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
你这个设计其实是用了职责链模式,这是很耗费性能的。

在MUD游戏这样实时系统中,最好使用真正Command模式,将你的职责链压缩,就成了真正Command模式,至于如何具体做,要了解整个系统架构才能找出实用具体的方法。
ajoo

悄悄话
发表文章: 64
注册时间: 2004年01月09日 07:39
Re: 请教一下,该如何重构或设计才好?? 2004年02月08日 07:52 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我倒不觉得职责链有什么效率问题。实际上,很多商业库,如果你跟踪进去,都是几十层的嵌套,如果设计时就对效率太过关心,只怕就什么也干不了了。

如何设计,还是从如何减小耦合,如何减少代码重复着手。实际上,只要接口设计好了,管它叫什么模式呢?
banq

悄悄话
发表文章: 9484
注册时间: 2002年08月03日 17:08
Re: 请教一下,该如何重构或设计才好?? 2004年02月08日 10:27 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
如何实现一个真正的Command模式,对于你这样和客户端交互的例子来说,MVC是你努力的方向,你将你的系统的Event Action以及View、后台Model处理关系理顺,一般Action处使用Command模式。

to ajoo:
商业库不代表它的性能质量好啊,职责链因为涉及一个请求多个环节处理,很显然,处理环节越多,性能越低啊。
zard222

悄悄话
发表文章: 7
注册时间: 2003年12月16日 13:27
Re: 请教一下,该如何重构或设计才好?? 2004年02月08日 20:51 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
关于mvc模式我想我是这样做的,客户端就是view,command就是control

关于vistor我需要想一下先,不过“ajoo跟椅子说'对不起'”这些语句是从数据库中读取的,我希望我的mud通过修改数据库就可以变成另外一个mud

我的command是这样实现的(稍作简化):
public interface Command
{
public boolean action ( String cmdParams) ;
}

/**
* 交谈命令
*/

public class TalkToCmd extends AbstractCmd
{
protected boolean action(String cmdParams)
{ //conn是action带的参数,我省去了
conn.getUserControler().talkTo(cmdParams);

return true;
}
}

public class CommandDispatch
{
private Map responseMap = new HashMap () ;

public void putCommand ( String cmdString , Command cmd )
{
responseMap.put ( cmdString.toUpperCase () , cmd ) ;
}

public boolean action ( String cmdLine)
{
//分解命令行,比如用户发来的是talkto aaa,那么就分成
//cmdString=talkto;cmdParams=aaa
return internalAction (cmdString , cmdParams ) ;
}

protected boolean internalAction (String cmdString ,String cmdParams )
{
boolean result ;
//find command to do
Command cmd = ( Command ) responseMap.get ( cmdString ) ;
if ( cmd != null )
{
result = cmd.action ( cmdParams ) ;
}
return result ;
}
}


public class JMudCommandDispatch
extends CommandDispatch
{
...
public static String CMD_TALKTO = "TALKTO" ;

//Login
public JMudCommandDispatch ()
{

//用户命令
...
putCommand ( CMD_TALKTO , new TalkToCmd () ) ;
putCommand ( CMD_GIVETO , new GiveToCmd () ) ;

}

public boolean action ( String cmdLine )
{
return super.action ( cmdLine ) ;
}
}
zard222

悄悄话
发表文章: 7
注册时间: 2003年12月16日 13:27
Re: 请教一下,该如何重构或设计才好?? 2004年02月09日 09:26 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
player不是只能和npc交谈,如果和玩家交谈就是私聊,npc和humanPlayer继承至player,实现talkto(),
板桥说的职责链压缩,不太明白怎么压缩
rypan

悄悄话
发表文章: 41
注册时间: 2003年09月13日 00:06
Re: 请教一下,该如何重构或设计才好?? 2004年02月09日 11:04 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
好像所有的mud都是使用心跳模式的吧?
banq

悄悄话
发表文章: 9484
注册时间: 2002年08月03日 17:08
Re: 请教一下,该如何重构或设计才好?? 2004年02月09日 12:16 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
如果你的客户端发送到服务器端是编号的,如1代表play 2代表stop等,
那么压缩成Command模式就方便多。

如果,你不能明确客户端是编号发出命令,那么也参考看看Web结构中,前台浏览器一般都是发送一种命令:get或post,虽然只是一种命令,但是可以携带各种参数,例如参数1代表play 2代表stop等,依然可以使用MVC模式。

你先需要确定MVC框架,然后才可真正使用command模式。

Struts是Web结构中MVC好的实现,建议参考。
ajoo

悄悄话
发表文章: 64
注册时间: 2004年01月09日 07:39
Re: 请教一下,该如何重构或设计才好?? 2004年02月09日 13:03 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我的意思是说,在java里面,对效率不能这么个计较方法。
其实,所以职责链效率低,不过是因为消息经过了若干次indirection。但是,OO里面,decorator, adaptor, bridge等等等等,几乎所有的pattern都是通过加入一个额外的indirection来获得灵活性的。

从java的角度来看,只要算法合适,设计上为了灵活性考虑多加入一两个indirection实在是不算什么。

如果设计时就考虑indirection的效率问题,那么对接口编程根本就实施不开。ioc也最好变成直接new一个实现了。
ajoo

悄悄话
发表文章: 64
注册时间: 2004年01月09日 07:39
Re: 请教一下,该如何重构或设计才好?? 2004年02月09日 13:53 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
几点意见:
1。对command的parse,应该在进入整体框架之前,就做好。你这个Command还带有一个命令字符串,这还是一个很原始的命令,肯定应该是command parser内部的数据结构,不应该公开到外部。我前面给的visitor的例子,里面的action已经是经过parse的纯逻辑的entity,和command语法和网络链接是完全没有耦合的。

2。用字符串来标识每一个command也不够灵活。每一个command应该是自描述的,不应该依赖外界的command name。

3。还是应该花心思在每个接口的需求和依赖关系,耦合上。我不同意banq的借鉴Struts的意见。实际上,struts作为一个web framework,我认为在这里的可借鉴的意义很小。
view和model当然要分开。但是,mud的view逻辑很简单,不过就是一些描述文字,所以,不要把问题复杂化。
zard222

悄悄话
发表文章: 7
注册时间: 2003年12月16日 13:27
Re: 请教一下,该如何重构或设计才好?? 2004年02月10日 10:52 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
谢谢板桥和ajoo 的意见
这个主题有 15 回复 / 2Go 1 2
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表    返回页首返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache 缓存 DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Seam Spring Struts
正在读取,请等待...
google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘 博采网摘
查询本论坛内 回复超过的热门帖子
     回复该主题贴
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
  发贴前查询 标签列表勿重复发表问题

RSS 手机阅读 add to google add to yahoo
解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com
anti spam