怎么进行“信息传递”

北大青鸟大学城校区logo 北大青鸟大学城校区
招生简章校园环境师资力量就业明星招生问答软件工程师北京大学学历学员项目联系我们 报名通道

免费在线咨询通道>>

免费在线报名通道>>

北大青鸟报名电话
当前位置:北大青鸟 > 北大青鸟 > 北大青鸟学员 >

怎么进行“信息传递”

标签:   分类:北大青鸟学员

“不要相信其他的对象。毕竟,它们是由别人写的,甚至有可能是你自己上个月头脑发昏的时候写的呢。从别人那里去拿你需要的信息,然后自己处理,自己决采。不要放弃控制别人的机会!”

“面向过程的代码取得信息,然后做出决策。面向对象的代码让别的对象去做事情。一A1ec sharp[sha97】通过观察后,一针见血螗指出了这个关键点。但是这种说法并不仅限于面向对象的开发,任何敏捷的代码都应该遵循这个方式。

作为某段代码的调用者,开发人员绝对不应该基于被调用对象的状态来做出任何决策。更不能去改变该对象的状态。这样的逻辑应该是被调用对象的责任,而不是你的。在该对象之外替它做决策,就违反了它的封装原则,而且为bug提供了滋生的土壤。

DavId Bock使用“送报男孩和钱包的故事’’很好地诠释了这一点。假定送报男孩来到你的门前,要求付给他本周的报酬。你转过身去,止送报男孩从你的后屁股兜里掏出钱包.并且从中拿走两美元(你希望是这么多),再把钱包放回去。然后,送报男孩就会开着他崭新的美洲豹汽车扬长而去了。

在这个过程中,送报男孩作为“调用者”应该告诉客户付他两美元。他不能探询客户的财务状况,或是钱包的薄厚,他也不能代替客户做任何决筻。这都是客户的责任,而不属于送报男孩。敏捷代码也应该以同样的方式工作。

与告知,不要询问相关的一个很有用的技术是:命令与查询相分离模式(command-queryseparation)。就是要将功能和方法分为“命令”和“查询”两类,并在源码中记录下来(这样做可以帮助将所有的“命令”代码放在一起,并将所有的“查询”代码放在一起)。

一个常规的“命令”可能会改变对象的状态,而且有可能返回一些有用的值,以方便使用。一个“查询”仅仅提供给开发人员对象的状态,并不会对其外部的可见状态进行修改。

小心副作用

是不是听到有人说过:“噢,我们刚调用了那个方法,是因为它的副作用。”这种说法等同于为代码中的诡异之处辩护说:“嗯,它现在是这个样子,是因为过去就是这个样子……”

类似这样的话就是一个明显的警告信号,表明存在一个敏感易碎的而不是敏捷的设计。

对副作用的依赖,或是与一个不断扭曲、与现实不符的设计共存,说明你必须马上开始重新设计以及重构你的代码了。

这就是说,从外部看来,“查询”不应该有任何副作用(如果需要的话,开发人员可能想在后台做一些事先的计算或是缓存处理,但是取得对象中X的值,不应该改变y的值)。

像“命令”这种会产生内部影响的方法,强化了告知,不要询问的建议。此外,保证“查询”没有副作用,也是很好的编码实践,因为开发人员可以在单元测试中自由使用它们,在断言或者调试器中调用它们。而不会改变应用的状态。

从外部将“查询”与“命令”隔离开来,还会给开发人员机会询问自己为什么要暴露某些特定的数据。真的需要这么做吗?调用者会如何使用它?也许应该有一个相关的“命令”来替代它。

告知,不要询问。不要抢别的对象或是组件的工作。告诉它做什么,然后盯著你自己的职责就好了。

切身感受

smalltalk使用“信息传递”的概念,而不是方法调用。告知,不要询问感觉起来就像你在发送消息,而不是调用函数。

平衡的艺术

一个对象,如果只是用作大量数据容器,这样的做法很可疑。有些情况下会需要这样的东西,但并不像想象的那么频繁。

一个“命令”返回数据以方便使用是没有问题的(如果需要的话,创建单独读取数据的方法也是可以的)。

绝对不能允许一个看起来无辜的“查询”去修改对象的状态。

若有疑问请拨打北大青鸟咨询热线:010-80146691或点击免费在线咨询!
  • xml地图 网站地图 招生简章 合作企业 学员项目 联系我们
  • 关闭窗口