一、定义:
观察者模式(Observer)又叫做发布-订阅模式(Publish/Subscribe),定义了一种一对多的依赖模式,让多个观察者对象同时监听某一个主题对象,这个主题对象在状态发生变化时,会通知所有观察者对象,使他们能够自动更新自己。
二、示例代码:
package com.pattern.observer;
import java.util.LinkedHashSet;
/*通知类*/
public class Notified {
/*用linkedHashSet防止有重复的订阅者*/
LinkedHashSet<SubscrSuper> list = new LinkedHashSet();
String message;
public void addSubscription(SubscrSuper subscriber) {
list.add(subscriber);
}
public void removeSubscription(SubscrSuper subscriber) {
list.remove(subscriber);
}
public void setMessage(String s) {
this.message = s;
}
public void notif() {
for (SubscrSuper subscriber : list
) {
subscriber.update();
}
}
}
package com.pattern.observer;
/*抽象观察类*/
public abstract class SubscrSuper {
protected String name;
protected Notified notified;
public SubscrSuper(String name,Notified notified) {
this.name = name;
this.notified=notified;
}
abstract void update();
}
package com.pattern.observer;
public class Subscriber extends SubscrSuper {
public Subscriber(String name, Notified notified) {
super(name,notified);
}
@Override
void update() {
System.out.println(notified.message+" "+name+" turn down");
}
}
package com.pattern.observer;
public class Subscrier2 extends SubscrSuper{
public Subscrier2(String name,Notified notified) {
super(name,notified);
}
@Override
public void update() {
System.out.println( notified.message+" "+name+" play basketball");
}
}
package com.pattern.observer;
public class Client {
public static void main(String[] args) {
/*通知类*/
Notified notified = new Notified();
/*订阅类*/
SubscrSuper subscriber =new Subscriber("Stoner",notified);
SubscrSuper subscriber2 = new Subscrier2("Vienna",notified);
/* 设置通知消息*/
notified.setMessage("notify boos come ");
/*给通知类添加订阅者*/
notified.addSubscription(subscriber);
notified.addSubscription(subscriber2);
/* 发出通知*/
notified.notif();
}
}
三、利用委托类实现
上述例子的问题在于。通知类依赖于抽象观察类,但是当观察类所用的方法不一样,提取不出一个通用抽象的观察类。
package com.pattern.observer;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/*事件类*/
public class Event {
/*调用的对象*/
private Object object;
/*方法名*/
private String methodName;
/*方法的参数*/
private Object[] params;
/*方法的参数类型*/
private Class[] paramTypes;
public Event(Object object, String methodName, Object... objects ) {
this.object = object;
this.methodName = methodName;
this.params = objects ;
initParamTypes(this.params);
}
/*初始化参数类型*/
private void initParamTypes(Object[] params) {
if (params==null){
return;
}
this.paramTypes = new Class[params.length];
for (int i = 0; i < params.length; i++) {
this.paramTypes[i] = params[i].getClass();
}
}
/*利用反射调用对象*/
public void invoke() {
try {
Method method = object.getClass().getMethod(methodName, paramTypes);
if (method == null) {
return;
}
else {
method.invoke(object, params);
}
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
package com.pattern.observer;
import java.util.ArrayList;
import java.util.List;
/*事件管理类*/
public class EventHandler {
/*事件列表*/
public List<Event> objects;
public EventHandler() {
this.objects = new ArrayList<Event>();
}
/*添加事件*/
public void addEvent(Object object, String methodName, Object... args) {
objects.add(new Event(object, methodName, args));
}
/*通知*/
public void notifyx(){
for (Event event:objects){
event.invoke();
}
}
}
package com.pattern.observer;
/*抽象通知者*/
public abstract class Notifier {
private EventHandler eventHandler = new EventHandler();
public EventHandler getEventHandler() {
return eventHandler;
}
/*增加观察者*/
public void addListener(Object object, String methodName, Object... args){
eventHandler.addEvent(object, methodName, args);
}
/*发出通知*/
public abstract void notifyx();
}
package com.pattern.observer;
/*具体通知者*/
public class ConcreteNotifier extends Notifier {
@Override
public void notifyx() {
System.out.println("开始发出通知");
this.getEventHandler().notifyx();
}
}
package com.pattern.observer;
/*具体的观察类*/
import java.util.Date;
public class PlayingListener {
public void PlayingListener() {
System.out.println("playing games");
}
public void shutDownGames(Date date) {
System.out.println("shut down games" + date);
}
}
package com.pattern.observer;
/*具体的观察类*/
import java.util.Date;
public class WatchingListener {
public void WatchingListener() {
System.out.println("watching tv");
}
public void stopWatchingTV(Date date) {
System.out.println("stopWatching tv"+date);
}
}
package com.pattern.observer;
import java.util.Date;
public class Client {
public static void main(String[] args) {
/*通知类*/
Notifier notifier = new ConcreteNotifier();
WatchingListener watchingListener = new WatchingListener();
PlayingListener playingListener = new PlayingListener();
notifier.addListener(watchingListener,"stopWatchingTV",new Date());
notifier.addListener(playingListener,"shutDownGames",new Date());
notifier.notifyx();
}
}