今天话题的由头来自于同 小涂 同学课间的讨论。小涂同学是在做 winForm 的开发时,遇到一个需求,想要用上 观察者模式(像不像一个接口?c#版是用委托加事件来实现的)。而跟小涂讨论的时候,我个人只是感觉稍微有点明白,但是 语焉不详 ,总感觉表达不清。后来证实,这的确是错觉,其实张老师说过的一席话是真理:如果不能把你懂得的东西明明白白说出来那是假懂,只有把不懂的新手也给说懂,那才是真正的懂。(想到 周星星 把死人骂活。。)
代理和 观察者 其实是两个真的有点不同的模式,只是 我们非英语语系国家的同仁,有点上当受骗的意思(完全可能是无法把握 英语 语义的真谛)。delegate这个单词的二义性导致很容易产生迷惑。我试图打个比方,希望能把我理解的意思(两者的区别)表述明白。
我要买HP笔记本,(假设)HP公司的笔记本总部在北京,我人在上海,显然购买起来有难度。但我可以找到 上海的徐家汇 太平洋数码广场,在里面找一家 HP代理商,由代理商向HP发一条‘request’要求购机(中间错综复杂的情节,并不需要我知道)。这里的关系是:我-->>代理-->>HP。
但是这个时候HP笔记本正好断供,代理告诉我,他已经将我的名字注册在HP北京总部(并且拿了号码,排名还比较靠前,至少不会像今年春运一样,排在第二位就买不到票)。代理说了,他能做的就是发出request,接收response的中介费他不高兴赚了。因为如果HP电脑有货了,HP北京的销售会直接打我手机。(销售什么时候打电话并不知道,但是一旦时机成熟,这个电话就会不期而至,需要我的手机时刻保持通话状态——我的手机就是一个‘回调函数’Handler——如果我愿意,我可以把自己的声音录下来,让手机直接回复HP销售)这里就是 观察者 模式的体现(而且HP笔记本到货刚好可以用.net Framework的事件机制加以理解)。这里的关系是:HP-->>注册信息-->>我。
前者代理模式,可以看一个 变体 情况就是,不只我一个人,我们全班9个同学都要买HP。结果,结构变成了 本杰200901班9位同学(多方)-->>代理(1方)-->>HP(1方)。
后者观察者模式,可以看一个 变体 相应的就是,我们9个同学的信息全都在HP进行了注册(估计小涂同学不用注册?

)。这样,结构就变成了 HP(1方)-->>注册信息(9个同学各自的信息,多方)-->>每位同学(多方)。
在.net框架中,可以类比的就是,当一个事件激发时,其实是调用了一个‘委托调用链’(观察者模式通常用 集合 来维护这些 对象的引用——很明显,.net是用 ‘委托调用链’ 来维护这些 方法的引用),会将(注册在)这个多路委托中的多个方法进行调用。