background image

 我在

RTX 上问了同事们这样一个问题:有三个类,A 包含了 B,B 包含了 C,A 只知道

B,B 只知道 C;现在 C 的一些信息需要告诉 A,有什么好方法吗?我现在只能通过 C 的事
件通知

B,然后再用 B 的事件通知 A,这样多了一层通知,显得不够简洁和快速。

  余同事问道:

A 包含了 B,B 包含了 C,而且已经限制了 A 只知道 B,B 只知道 C,为

何还需要交换信息呢?

  我解释道:

C 相当于最底层,A 相当于界面层,B 相当于中间的一个包装,包装了包

C 在内的一些类,而 A 只需要知道 B 即可。现在需要将 C 的一些信息(比如状态信息)

反馈到

A,由 A 显示出来。

  另一个同事表示也遇到了很多次类似的问题,而且都是采用事件层层通知来解决的。余
同事认为,如果调用顺序是

A 调用 B,然后 B 调用 A,那么信息返回的顺序由 C 返回给

B,再由 B 返回给 A 是非常正常的。对于同步调用而言,的确如此,可是我现在遇到的问题
是,

A 必须调用了 B 后才能知道 C,事实上更为复杂:A 异步调用 B,B 异步调用 C。

  余同事说:那就采用类似于

CM 的消息订阅。不过还是推荐从结构上去避免这种问题。

消息订阅在范围上有点

“泛滥”,可能允许关注到不该关注的东西。异步一般选用消息订阅,

同步一般选用方法返回结果。

  我有点迷惑,从结构上去避免这种问题?难道上面所说的类结构不是很常见的吗?即
使不常见,也总会遇到某个类想要跳过某一层类通知另一层类的结构吧?不过消息订阅的
确是一个好的解决方案,尤其是对于多层结构的类或者是不同模块的类,但对于上面所说
的结构,用消息订阅就感觉有点像用牛刀杀鸡了。如果语言本身能提供消息订阅机制,那就
太好了。但余同事认为语言本身当然不提供,自己去海选一个库就行了。我却对此持反对意
见,比如

C++就没有提供事件通知机制,C#和 Java 都有,说不定以后会有一门新语言能完

美地提供消息订阅机制。

  余同事还给出了另外一种另类的方案:定义一个

Commond 类,A 去注册 Common 类

的事件,那么不管

B 里有 C、有 D 还是有其他类,都可以通过调用 Common 类对象去触发

事件,如此一来就减少了事件通知的次数。对于我提出的问题,这个方案显然没有直接采用
事件通知更为直接、明了和方便。但是这种方案在某些场景中却大有作为,比如在多个模块
中各自有不同的类,它们都想通知同一个类去做某一件事,或者某几件事,那么这个类只
需要注册

Common 类的事件,而其他所有类只需要调用 Common 的事件通知函数就可以了。

  基于上述讨论,我总结道:如果层层通知所跨的层次只有两层左右,那么采用事件机
制就能完美解决;如果层层通知所跨越的层次比较多,或者属于不同模块的通知,那么采
用消息订阅是最好的方法。

  但余同事告诫我不应该从通知的层数去考虑这种问题。他的想法是跟层数无关,而是跟
是否关注权限控制

/调用控制有关。如果关注权限控制和调用控制,即便层数再多,也应该

采用这种层层通知的方式去解决。他继续说道:这个

“权限”类似于我们用的用户权限,但它

又主要是指调用方面的

“安全验证”。比如你的 DLL 有关闭系统或者格式化磁盘之类的操作,

想限制调用者,最靠谱的方法应该是被调用者那边去限制。即,层层传递的时候,下一层能