游戏开发论坛

 找回密码
 立即注册
搜索
楼主: 月下临风

关于委托的一些想法

[复制链接]

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-30 09:04:00 | 显示全部楼层

Re: Re:关于委托的一些想法

congy: Re:关于委托的一些想法

委托不一定能降低耦合,我们不能只看到委托方,还要看被委托方,实际上被委托方是必须要知道委托方的属性的...



A类是用户,B类是商家,C类是厂家
只是C需要知道B和A的存在,用户不需要知道C的存在,如果不用委托,用户也需要知道修理厂的存在了,能作修理的不一定只有C厂,可能还有D厂E厂,C厂家做不了的事情,B可以帮A找D厂E厂...,用户根本和厂家就没有直接关系,A也不一定要知道关于厂家的属性,是谁帮用户生产和修理,用户更本不用关心,这怎么不是降低耦合?这和现实生活很相似的。 委托就是为了“解耦”和 “抽象重用”

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2007-10-30 09:49:00 | 显示全部楼层

Re: 关于委托的一些想法

A类是用户,B类是商家,C类是厂家
只是C需要知道B和A的存在,用户不需要知道C的存在,如果不用委托,用户也需要知道修理厂的存在了,能作修理的不一定只有C厂,可能还有D厂E厂,C厂家做不了的事情,B可以帮A找D厂E厂...,用户根本和厂家就没有直接关系,A也不一定要知道关于厂家的属性,是谁帮用户生产和修理,用户更本不用关心,这怎么不是降低耦合?这和现实生活很相似的。 委托就是为了“解耦”和 “抽象重用”


大家再去研究研究把。

我们现有的设计方式都是基于面向对象的代码级的模式。有一个原则是:你重用的代码越多,耦合度越大。

虽然说用户和工厂之间分工明确了,但是用户对工厂的依赖增加了,如果是回到自给自足的封建社会,用户自己生产,根本就跟工厂一点关系都没有了,这才是降低耦合度。

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-30 11:48:00 | 显示全部楼层

Re:关于委托的一些想法

ls的意思就是说分工就是降低程序的耦合性了,什么都写在一起才叫没耦合?
那你知不知道面向接口有什么好处?

再想想,如果A找B 然后B通过接口再去找C或D这些厂商,那么A就不依赖C厂商也不依赖D厂商,我们甚至可以通过配置给程序 inject 注入厂商(甚至写成插件式的方式),这是现在最流行的AOP面向方面的编程模型,其最大的优势就在于解耦,而这中间是比较需要委托做中介的。

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2007-10-30 12:22:00 | 显示全部楼层

Re:关于委托的一些想法

那你知不知道面向接口有什么好处?

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-10-30 12:56:00 | 显示全部楼层

Re:关于委托的一些想法

我的表达的确有些问题……
这么说吧,比如基类里有一个protected的函数func1,那么对于外部访问者而言,这个基类是不允许外部访问者知道这个func1函数的,但是假如派生类不需要知道这个函数也能完成自己的任务,但是把这个函数定义为protected可以为以后的改变提供灵活性,那么就意味着派生类不需要知道这个函数就能很好的工作了,但是如果以后需要,派生类还是可以访问这个函数的,这就是“不需要知道,但是如果有必要,能够知道”的情况。

所以我写的类里大部分的成员都是protected的,只有明确一个成员是不应该被派生类所知道的,我才把它变成private的。
但是还是觉得很难掌握平衡。

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2007-10-30 23:30:00 | 显示全部楼层

Re: Re:关于委托的一些想法

tonykee: Re:关于委托的一些想法

ls的意思就是说分工就是降低程序的耦合性了,什么都写在一起才叫没耦合?
那你知不知道面向接口有什么好处...

“A找B 然后B通过接口再去找C或D这些厂商”这里 A 与 B 就是耦合,“B 通过接口”这里又多了一个 B 的接口耦合,至少 B 要知道接口的定义,为了一个简单的功能,要维护这么复杂的关系,其实很不值得。从现实角度来讲,社会分工越细,要做的准备工作越多,实际上就越依赖于一定的基础规则,一旦不满足基础规则的需求出现,整个的底层规则就会受到质疑。我并不反对使用委托或者代理,我是建议根据实际的需要去选择,如果建立规则体系的好处很大,并且能在未来一段时间内满足需求上的扩展,就可以用,否则慎用。建议看一下敏捷软件开发中关于设计模式的部分。

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2007-10-30 23:38:00 | 显示全部楼层

Re: Re: Re:关于委托的一些想法

tonykee: Re: Re:关于委托的一些想法




A类是用户,B类是商家,C类是厂家
只是C需要知道B和A的存在,用户不需要知道C的存在,如果不用委托,...

你要看到所谓的解耦不是零代价的,是有一定成本的,这里解耦了,那里就会增加耦合,虽然用户和厂商没有耦合,但是厂商却与产品产生了耦合。拿 LZ 的例子来说,虽然窗口类对象与自身属性解耦,但是却增加了 io::XMLReader 与 Wnd::porperty 的耦合,所以看事物不能看一面,全面地权衡才会做出最好的设计。

119

主题

1367

帖子

1393

积分

金牌会员

Rank: 6Rank: 6

积分
1393
发表于 2007-10-30 23:48:00 | 显示全部楼层

Re:关于委托的一些想法

是啊,事物总是有两面性的,设计模式这东西也不能过渡追求,用的不好也会降低代码的可读性,而增加维护成本,所以用的适当,保证灵活,简洁,高效,可读性强才是硬道理,只是很多方面不能兼顾难以权衡,必要时可以考虑在某些方面作出适当牺牲

29

主题

405

帖子

405

积分

中级会员

Rank: 3Rank: 3

积分
405
 楼主| 发表于 2007-11-1 22:47:00 | 显示全部楼层

Re:关于委托的一些想法

最近两天忙着写世界编辑器,一直没空来这说两句,也许我的表达不是很清楚,确实,一开始我自己都没想好就说了,现在我整理了一下我的思路重新表述一下。

再解释一下委托和代理:
如果我买了台xbox360,我把它弄坏了,我想找ms的代理修,结果找不到,或者我发现那个代理不在中国,我只好找委托人去帮我解决这个问题了。
在类库或者服务方思考,我设计一套服务,那么我必须还要设计这套服务怎么服务于不同人的需求,设计代理就是解决这个问题的一个方法。
如果站在使用者和被服务者的角度看,我要需求一种服务,我可以自己解决,解决太麻烦的话我可以自己找服务,如果那个代理在我可见范围内,则我不需要委托就可以了。除非我实在一点办法也没有,就只好找委托,或创建委托。
一般我们开发游戏,引擎程序都和逻辑程序在一起,逻辑程序有什么需求只要提给引擎程序,一般都可以解决。
而且我们一般都把代理设计成全局的,这样的话一般情况下都直接用代理解决了,所以楼上的说代理就是委托。
如果引擎不能随便修改的话,如果代理的设定有严格的可见限制,那么有时候就需要委托了。


需求的产生:
UI编辑器,当时希望于UI库无关,UI库都是已经设计实现好的。
场景编辑器,于引擎无关。
游戏的场景系统。

我的思路和做法:
先说编辑器,编辑器实质上都是一个壳,要做到和内核无关也是很自然的想法。
UI编辑器和场景编辑器,站在编辑器的角度上看实质上也没什么差别,编辑器要做的事情很简单,方便游戏设计者编辑游戏中对象的属性。

我做好了编辑器的壳,用extream toolkit确实很方便,3大类一堆就出来了,而且做的和vs差不多,这也是我想要的,要什么对象直接从控件面板上拖过来,旁边是场景的对象层次关系,和属性列表,中间是显示主界面,下面一个输出窗口。
场景系统框架也写好了,场景系统的所有信息我都保存在我事先定义好的xml文件里面,xml确实牛叉,里面有继承也有模板不用它我真的不知道用什么更好了,这些反正都交给引擎的IO代理上解决。
现在我想要把游戏里的对象,3D物件和UI的属性读到编辑器里去。
这里我有个问题,很多引擎都是带了一套编辑器,我想他们的做法都是编辑器向引擎兼容了,这样做也确实没什么不好的,毕竟做编辑器简单,以后大不了重新写个,谁会为了编辑器去重新写引擎呢?而且引擎尽量保持简洁强悍也是一大卖点。
但对我个人来说,今天在这家公司,以后可能离开了,如果编辑器太依赖引擎(也是由我和另外一个程序来写),以后我写的这个编辑器就没用了。所以我打算为编辑器设计一个简单的委托方式,也就是最基本的数据结构的定义和转换。

编辑器只认委托方,但委托方是不可能直接从引擎解析出数据的,具体怎么解析交给引擎的代理,引擎根本不需要管他有没有编辑器,编辑器也不需要管他有没有引擎,反正他只负责把属性的数据传来修改再传去。
注,委托和代理肯定都是dll,如果是lib,这样做就没意义了,因为我假设不改动引擎和编辑器的情况下。
也有人可能觉得为什么不做成一个呢,把委托和代理集中在一起做了,就像一个中间件一样。但这样的话这个中间件就是把这个引擎和这个编辑器联系在一起,这也可以,不过这对我似乎没多大好处,我想把这个编辑器变成自己的私有财产。而且还有UI部分,以后可能会换来换去,感觉还是往这个目标做会更好点。
最后的工作量也不是太大,主要就是集中在,由IO的代理解析出数据后,再由编辑器的委托把这些数据转换成编辑器认可的格式,传给编辑器。
以后如果换其他引擎了(我想它是带IO文件解析组件的),编辑器部分只需要给编辑器的委托增加一种转换算法,这个可以用策略模式来解决,也不是太麻烦。

我前段时间一直在想要不要在场景系统中用委托,而我的问题大部分是代理设计的不全面而且可见性不是全局造成的。后来觉得还是不要委托算了,直接增加代理,并设成全局的,这样就OK了,在游戏中又设代理,右设委托太乱了点。反正服务多点也不是件坏事,我是这样想的。
Shall I made me understood?

36

主题

1047

帖子

1147

积分

金牌会员

Rank: 6Rank: 6

积分
1147
发表于 2007-11-1 23:40:00 | 显示全部楼层

Re:关于委托的一些想法

看了这么一大段,似乎楼主主要是想解决编辑器数据格式转换的问题,从这个角度来讲,楼主的方案是可行的,但是要想做到 Editor 和 Engine 完全分离,实际上很困难,而且也毫无必要。举个实际例子来说,比如 Editor 中希望能调节 Object 的空间位置,这一般都会通过编辑器的 UI 操作落实到 Engine 的 Transform 上,也就是 Matrix,但问题是每个 Engine 的几乎都有自己的 Matrix 类定义,楼主如何统一呢?如果 Editor 不想知道具体的 Matrix 类型,就要在委托中实现一个 Matrix 抽象类型,在 Editor 中去调用这个抽象来完成变换,但是每个引擎的坐标系统可能会不同,左右手坐标系也可能会不同,矩阵的左右乘法则也不会相同,还有 行优先和列优先的不同,甚至会出现像 doom3 sdk 中 Matrix3 和 Matrix2、Matrix4 是 Transpose 关系的复杂情况,这些如果考虑到的话,最后的抽象就是实现了的 Matrix 接口。这还只是数学库一小部分,还有 Vector\Quaternion\Euler 等等数学基础库,如果都抽象出来,工作量也不小。与此类似,引擎其它的部分也会出现同样的情况,如果按照这个思路作下去,为了保证 Editor 的完全独立性,就不敢把引擎的接口直接暴露给 Editor,这样能传给委托的都是些基本数据,Editor 的大部分逻辑都要放在委托中去实现,这样的 Editor 就是个 UI 壳和一些简单的逻辑,为了这个功能去实现委托我认为不值得,楼主不妨换个角度想想,编辑器的功能本来就是多变的,每个游戏的编辑器的需求都不尽相同,实际上能重用的部分并不多,引擎也并不是经常更换,所以直接去实现编辑器的功能要比编辑器和引擎分离要重要的多。
另外,我不明白楼主说的代理指的是什么,为何不直接使用引擎?代理并不能带来更多的好处,反而会增加对象和接口管理的复杂性。还有对于不使用 static lib 的观点我不敢苟同,如果希望编辑器和引擎在运行时切换,那是应该采用 dll 方案,但是这种情况其实很少,甚至实际当中就没有。static lib 也可以实现模块的多态性,只不过是编译时,而不是运行时。如果希望发布对应某个引擎的编辑器,只要编译对应的版本就行了,何苦还要做 dll 的动态管理呢?像 OGRE 那种采用 dll 方式实现运行时切换图形 API 的功能我认为华而不实,反而增加了架构上的复杂和维护上的困难。
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-6-19 06:05

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

快速回复 返回顶部 返回列表