免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 3681 | 回复: 9
打印 上一主题 下一主题

如何在对象间高效率传递我的上下文对象并令其改变能够自动传出? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2011-11-22 08:30 |只看该作者 |倒序浏览
我自己搞了个上下文对象Context,然后每个相关对象都用setContext(Context &)方法设置其上下文。现在问题是:这个setContext()方法的实现就是:
class My{
public:
  void setContext(Context &ctx){_ctx = ctx;}
protected:
  Context _ctx;
}

这种虽然传进来的是引用,但内部的赋值却是对象赋值,效率比较低。同时,内部_ctx的改变无法自动传出。
如果用指针当然简单,但指针总伴随着安全问题,能不用尽量不用。
不知有什么别的办法可以实现我的要求?
先说谢谢了!

论坛徽章:
0
2 [报告]
发表于 2011-11-22 08:42 |只看该作者
smart pointer

论坛徽章:
0
3 [报告]
发表于 2011-11-22 08:45 |只看该作者
优化一下Context:: operator=的性能,别老打接口上的主意:既然你允许直接用operator=,那么就需要考虑它的开销。真要改不了就别用Context当参数了,用智能指针或者再多弄个代理对象出来,不过搞不好更慢。
至于通知内部状态的变化,和你这里要求效率高是矛盾的。

论坛徽章:
0
4 [报告]
发表于 2011-11-22 10:10 |只看该作者
智能指针由于有托管问题,一旦赋值外部就引用不到了,必须再通过被调用类的另一个方法传出来,因此貌似不好用(如果不托管又会出现引用计数错误问题)。
开销只是一个问题,关键的还是内部状态变化要能自动传出。

论坛徽章:
0
5 [报告]
发表于 2011-11-22 10:35 |只看该作者
1、context对象如何产生?由谁负责维护?由谁改变状态?

正常来说,这个东西应该只需一份。明确了维护者,也就明确了归属。其它人直接用引用即可——如有必要,用const阻止它们修改。

理清楚这个问题,下一步才可以去考虑效率(事实上,理清楚这个,就没必要考虑效率了)。


2、状态变化传出——传给谁?框架还是一组对象?传递方式是同步还是异步?

如果是一组对象,可以考虑观察者模式;如果传给框架,context被修改时调用框架的回调接口即可。

传递方式是同步,就直接调回调函数;是异步,就post一个消息到消息队列——至于消息队列是利用系统已有实现还是自己做,你自己根据情况看。




总的来说,你这个明显是先编码后设计。这才导致contex归属不明、管理混乱(效率倒在其次);状态通知更是毫无头绪,就是依我的意见用观察者模式解决了,也是生硬加入,和炫耀技巧无异——甚至还不如炫耀技巧,至少炫耀技巧的人头脑可能还是清晰的、有通盘考虑的;
要是通知还需要异步效果,那么消息队列之类显然现在也还不存在,临时做一个凑合的确可以;但消息如何产生?空间如何分配?如何回收?都由谁负责?这些不提前考虑好,等后面需求明确了,就使劲打补丁吧。

论坛徽章:
0
6 [报告]
发表于 2011-11-22 14:54 |只看该作者
正因为Context只有一份,而所有使用者都可以对其进行权限内的更改,所以才出现我所说的信息共享问题。对这个问题,可能有两种做法:
1、回调。这要求大家都具备某个统一的回调接口,在类的设计上要求源自共同的基类,同时对代码结构也有要求。目前这个模式不适合。
2、外部传参,可通过编程规范或构建方法参数强制传入。其实二、三楼方法已经是一种解决方案,只是我还在考虑是否有更好的做法而已。

至于编码和设计的先后问题,首先我不是大师,又是一个人,做不到将所有的系统架构设计细节了然于胸后才开始编码。我能做的,就是按我所能,设计出一个最基础的系统框架,验证其可行性,验证其效率,排除存在的主要技术障碍。然后,才是根据细化的要求将其完善成一个可用的框架,最后是将它交付给其他人,由他们在其基础上完成具体的功能实现。所以说,在初步设计和可行性还不明确的阶段,适当编码验证有什么错???

论坛徽章:
0
7 [报告]
发表于 2011-11-22 15:12 |只看该作者
1、如果context只有一份,那么就没有复制的需求。不然改了你还得复制回去。

如果你纠结的所谓“通知”就是这个的话,我只好无语了。

2、一看你这一套一套,就知道这套理论是从哪来的了
算了,我绕道走。

论坛徽章:
0
8 [报告]
发表于 2011-11-22 17:50 |只看该作者
1、Context本来就不需要复制,我纠结的只是如何将它变为自己的属性便于使用并能将更改反映到整个调用链条上。还请仔细看我的帖子,和二、三楼的回复。
2、很莫名,不知你想到了什么理论来源?除了大家都学过的开发语言教科书,我没看过那些高深的模式、方法,如果你一定说有理论,只能说是山野理论,从工作中得来,或许与正统的有点差距

论坛徽章:
0
9 [报告]
发表于 2011-11-22 18:15 |只看该作者
本帖最后由 狗蛋 于 2011-11-22 18:30 编辑

1、虽然没和二三楼交流过,但我仍然可以肯定,他们被你问问题的方式误导了;或者说,在你后面补充这些东西之前,他们根本不会想到会是这么蠢个问题。


首先,既然Context不需要复制,也就是说context并不属于My这个对象,那你在类里面声明context对象干嘛?
这不仅仅是复制效率问题,还有内存空间占用问题。

其次,既然它只有一份,用singleton模式管理,需要用时再取出来不就好了?
你完全可以用hash_map之类管理一大组的context,然后用递增的int做key,在My里面保留key就行了。一样不需要指针。
——你可以把singleton理解为文绉绉的全局变量。

最后,这个context更改反应到整个调用链条上是什么意思?
是要触发其它对象的什么动作,还是其它对象之后被其它逻辑访问时,可以知道context已经改变了?

如果是前者,那么你还是需要一个消息机制或观察者模式;如果是后者,不要画蛇添足的在My里面声明那个诡异的context对象就行了,不需要多写一行代码。


2、本来怀疑你中敏捷理论的毒了,搞无设计反复重构。
设计并不是教科书/UML搞的那些正经八百的东西,而是预先规划。
就好像你这个东西一样,我只凭你的片言只语,就可以知道要做好,需要哪几个部分、各部分如何分工合作。这寥寥几句就是设计。

不管你东西做再大还是再小,肯定事先要考虑如何做出来(比如我之前问的,context由谁生成、由谁维护;何谓通知等等),这个考虑就是设计。

如果能进一步考虑如何才能做好、模块间要交流什么信息、信息格式如何,并形成成文文档,这就是很不错的设计了。至少这东西可以保证除非很特殊的情况,软件一定能做出来。

有了以上的哪怕仅仅第一步,都有资格说是先设计后编码。否则,你现在这种做法,就是撞大运编程甚至霰弹式编程:
http://bbs.chinaunix.net/thread-3621689-1-1.html

论坛徽章:
0
10 [报告]
发表于 2011-11-22 18:47 |只看该作者
不知道你要做什么,大致说下我的理解:

1、你这个系统是事务性的,每个事务有自己的上下文(context)
2、系统中的一些组件通过访问/修改事务上下文完成任务
3、其它组件并不需要context改变之类的通知

那么,显然事务上下文需要一个机制来单独管理。

如果是单事务的,用全局变量/singleton即可;其它组件直接访问全局变量/singleton里这个context
如果是多事务的,用全局map或singleton管理的map管理这些事务。其中每个事务对应一个事务ID,可以用整形数表示——这玩意儿在一些系统里叫session id:这样其它组件只要知道session id,就能找到对应的context。

——上面这一小段话,就是设计。有这个,其它写组件的人就不至于茫然不知所措。
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP