对象间通信方式有多种,以下仅仅考虑最基本的几种方式:
假设两个对象A和B需要通信,分三种情况考虑:
(一)A和B互相持有对方的引用,此时通信最简单,都可以互相直接调用。
(二)对象A直接持有对象B的引用,反过来B对象不持有A对象的引用
(1)A对象可以直接使用B对象的方法和属性。
(2)B对象不持有A对象的属性,则不能直接调用。此时对象B需要A配合完成某项工作,常常采用的方式:基本事件方式,委托持有,EventBus方式。
对于基本事件方式,即B中定义事件,A在获得B引用的时候就订阅B中的事件。当B引发事件的时候,执行A中的方法。如果需要交互,可以通过双事件或多事件的方式,即B中引发一个事件,A中执行并改变B中的某个状态,然后B中执行一些工作,后面再次引发另一个事件,在A中执行另外的工作,但这种方式比较麻烦,用得很少,但特殊情况还是有用的,比如多个A对象关注了一个B对象,而不同A对象收到B对象事件时,所执行的代码需要依据引发次序(第一个执行的A对象可以改变B对象的某个状态,其它执行的A对象就会改变自身的执行行为)来判断时。
对于委托持有方式,常见的是B对象的生命周期要小于A对象的生命周期,比如B由A创建,并由A销毁(或者随着A的销毁而销毁),且只对A负责时(比如是A的一部分),此时直接持有A对象的delegate也比较方便。即A对象获得B对象引用时,直接将自身的方法通过delegate传给B。在B中可以直接调用该delegate,即执行的A对象的方法。***当A的生命周期小于B的生命周期的时候,A销毁后,B依然持有delegate,这样会产生问题。***当B与多个A交互时,B可能无法持有多个A的委托,或持有多个A的委托比较复杂时,这种方式就会比较麻烦或容易出现问题。
通过EventBus通信,本质上是通过公共的第三方来收集并分派事件,可采用第三方库来实现,比如Prism中的IEventAggregator。使用此方式的,通信双方都需要直接或间接持有IEventAggregator的实例对象,A中订阅事件,B中发布事件,完成通信。
(三)对象A互相不支持有对方的引用
虽然B不直接持有A的引用,但是当B能够很方便通过间接方式获取A对象的引用或delegate时,基本事件方式、委托持有方式也比较方便使用。否则,相对简单的方式就是通过EventBus来使用订阅-发布方式。