觀察者設計模式其實就是一種發布預訂的設計模式,大家都知道JMS裡面有發布預訂的模式,也就是有一個一對多的關系,一個發布者,然後有N多個消費者,一旦發布者發出消息,那麼所有預訂的消費者都將收到消息。
一般的實現方法大家可能都很熟悉了;
1.傳統觀察者設計模式編寫方法:
舉例說明:
發布者類:Publisher.java
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Publisher implements Subject {
private List subs= new ArrayList();
private String msg;
// this message is added so I can give
// this class a reason to call notifyListener.
public void setMessage(String message){
System.out.println("我是發布者,我說:" + message);
this.messageText = message;
this.notifyListeners();
}
public void addListener(Subscriber o) {
this.subs.add(o);
}
public void removeListener(Subscriber o) {
if (this.subs.contains(o)){
this.subs.remove(o);
}
}
// call the update method on
// each Subscriber
public void notifyListeners() {
for (Iterator iter = subs.iterator(); iter.hasNext();) {
Subscriber listener = (Subscriber ) iter.next();
listener.update(msg);
}
}
}
預定者類:Subsriber1.java
public class Subsriber1 implements Observer {
public void update(String messageText) {
System.out.println("我的名字是: " + this);
System.out.println("我接收到消息: " + messageText);
}
預定者類:Subsriber2.java
public class Subsriber2 implements Observer {
public void update(String messageText) {
System.out.println("我的名字是: " + this);
System.out.println("我接收到消息: " + messageText);
}
如果按傳統的觀察者模式編寫方法,如果要把發布者和預訂者聯系在一起的話;還需要有專門的處理類來負責添加這種聯系。
例如:
public class ExampleRun {
public static void main(String[] args) {
Publisher pub = new Publisher();
Subsriber1 sub1 = new Subsriber1();
Subsriber2 sub2 = new Subsriber2 ();
pub.addListener(sub1);
pub.addLstener(sub2);
pub.setMessage("大家好啊");//廣播消息
}
}
傳統的觀察者設計方法發布者和預定者的聯系是硬編碼在程序裡面的。
2。采用spring進行優化
首先你肯定要熟悉spring的bean工廠配置原理。
bean工廠的xml配置文件如下:<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN"
"http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="sub1" class="Subsriber1"/>
<bean id="sub2" class="Subsriber2"/>
<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>
這裡的關鍵是采用org.springframework.beans.factory.config.MethodInvokingFactoryBean工廠類;來動態
把sub1和sub2注入到pub當中。實現觀察者的xml可配置化。
處理類如下:
import org.springframework.context.ApplicationContext;
import org.springframework.context.support.FileSystemXmlApplicationContext;
public class ExampleRun {
public static void main(String[] args) {
ApplicationContext ctx = new FileSystemXmlApplicationContext(
"/config/ObserverTest.xml");
Pub pub = (Publisher) ctx.getBean("pub");
pub.setMessage("大家好啊!!!");
}
}