觀察者模式本質為發布-訂閱模式:一個發布者,多個訂閱者,發布消息時所有訂閱者均收到通知。傳統實現將發布者與訂閱者關係硬編碼,靈活性差。本文展示如何利用Spring IoC容器實現關係的XML配置化。
定義Subject接口(addListener、removeListener、notifyListeners)、Observer接口(update)。Publisher維護List,調用setMessage時遍歷通知。Subscriber1、Subscriber2實現update打印消息。ExampleRun中手動addListener綁定關係(代碼片段見原文)。缺點:綁定邏輯硬編碼,修改需重編譯。
利用org.springframework.beans.factory.config.MethodInvokingFactoryBean在容器啟動時動態調用Publisher.addListener注入訂閱者。配置文件ObserverTest.xml:
<beans>
<bean id="sub1" class="Subscriber1"/>
<bean id="sub2" class="Subscriber2"/>
<bean id="pub" class="Publisher"/>
<bean id="bindPubAndSub"
class="org.springframework.beans.factory.config.MethodInvokingFactoryBean">
<property name="targetObject"><ref local="pub"/></property>
<property name="targetMethod"><value>addListener</value></property>
<property name="arguments">
<list>
<ref bean="sub1"/>
<ref bean="sub2"/>
</list>
</property>
</bean>
</beans>
啟動類ExampleRun僅獲取pub Bean並調用setMessage:
ApplicationContext ctx = new FileSystemXmlApplicationContext("/config/ObserverTest.xml");
Publisher pub = (Publisher) ctx.getBean("pub");
pub.setMessage("大家好啊!!!");
優勢:發布者/訂閱者解耦,關係外置配置,無需修改代碼即可增減訂閱者,符合開閉原則。