定义:观察者模式(有时又被称为发布-订阅模式、模型-视图模式、源-收听者模式或从属者模式)是软件设计模式的一种。在此种模式中,一个目标物件管理所有相依于它的观察者物件,并且在它本身的状态改变时主动发出通知。这通常透过呼叫各观察者所提供的方法来实现。此种模式通常被用来实作事件处理系统。
jdk当中嵌入了观察者模式以下是简单理解的demo读者与作者之间 读者作为观察者 作者作为被观察者public class Reader implements Observer{private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public Reader(String name) {this.name = name;}//关注public void subscribe(String writerName){WriterManager.getInstance().getWriter( writerName ).addObserver( this );}//重写通知方法 通知观察者发生的改变@Overridepublic void update(Observable o, Object arg) {if (o instanceof Writer) {Writer writer = (Writer) o;System.out.println("优秀的偷窥了"+writer.getName());}}}//作者 被观察类 继承Observablepublic class Writer extends Observable {//数据名称private String name;public String getName() {return name;}public void setName(String name) {this.name = name;}public Writer(String name) {super();this.name = name;//添加作者WriterManager.getInstance().add(this);}//作者发布新小说了,要通知所有关注自己的读者public void addNovel(String novel) {System.out.println(name + "发布了新书《" + novel + "》!");setChanged();notifyObservers();}//创建一个类用于对观察者和被观察者进行管理//管理类public class WriterManager {//被观察者列表private Map <String, Writer> writerMap = new HashMap <String, Writer>();//添加作者public void add(Writer writer) {writerMap.put( writer.getName(), writer );}//根据作者姓名获取作者public Writer getWriter(String name) {return writerMap.get( name );}//单例private WriterManager() {}//作者是单例的public static WriterManager getInstance() {return WriterManagerInstance.instance;}private static class WriterManagerInstance {private static WriterManager instance = new WriterManager();}}public class ClientMain {public static void main(String[] args) {Writer w1 = new Writer("王八蛋");Reader reader=new Reader( "张三");Reader reader1=new Reader( "李四");reader.subscribe( "王八蛋" );reader1.subscribe( "王八蛋" );//七哥和刘能还关注了王小蒙w1.addNovel( "Message" );}}-------------------------------------------------运行结果:王八蛋发布了新书《Message》!优秀的偷窥了王八蛋优秀的偷窥了王八蛋
事件驱动
1,观察者模式中观察者的响应理论上讲针对特定的被观察者是唯一的(说理论上唯一的原因是,如果你愿意,你完全可以在update方法里添加一系列的elseif去产生不同的响应,但LZ早就说过,你应该忘掉elseif),而事件驱动则不是,因为我们可以定义自己感兴趣的事情,比如刚才,我们可以监听作者发布新书,我们还可以在监听器接口中定义其它的行为。再比如tomcat中,我们可以监听servletcontext的init动作,也可以监听它的destroy动作。2,虽然事件驱动模型更加灵活,但也是付出了系统的复杂性作为代价的,因为我们要为每一个事件源定制一个监听器以及事件,这会增加系统的负担,各位看看tomcat中有多少个监听器和事件类就知道了。3,另外观察者模式要求被观察者继承Observable类,这就意味着如果被观察者原来有父类的话,就需要自己实现被观察者的功能,当然,这一尴尬事情,我们可以使用适配器模式弥补,但也不可避免的造成了观察者模式的局限性。事件驱动中事件源则不需要,因为事件源所维护的监听器列表是给自己定制的,所以无法去制作一个通用的父类去完成这个工作。4,被观察者传送给观察者的信息是模糊的,比如update中第二个参数,类型是Object,这需要观察者和被观察者之间有约定才可以使用这个参数。而在事件驱动模型中,这些信息是被封装在Event当中的,可以更清楚的告诉监听器,每个信息都是代表的什么。
读者
package com.md.readerAndEvent;
public class Reader implements WriterListener {
private String name;
public Reader(String name) {
super();
this.name = name;
}
public String getName() {
return name;
}
//读者可以关注某一位作者,关注则代表把自己加到作者的监听器列表里
public void subscribe(String writerName) {
WriterManager.getInstance().getWriter( writerName ).registerListener( this );
}
//读者可以取消关注某一位作者,取消关注则代表把自己从作者的监听器列表里注销
public void unsubscribe(String writerName) {
WriterManager.getInstance().getWriter( writerName ).unregisterListener( this );
}
@Override
public void addNodel(WritertEvent writerEvent) {
Writers writer = writerEvent.getWriter();
System.out.println( name + "知道" + writer.getName() + "发布了新书《" + writer.getLastNovel() + "》,非要去看!" );
}
}
作者
package com.md.readerAndEvent;
import java.util.HashSet;
import java.util.Set;
public class Writers {
private String name;//作者的名称
private String lastNovel;//记录作者最新发布的小说
private Set <WriterListener> writerListenerList = new HashSet <WriterListener>();//作者类要包含一个自己监听器的列表
public Writers(String name) {
super();
this.name = name;
WriterManager.getInstance().add( this );
}
//作者发布新小说了,要通知所有关注自己的读者
public void addNovel(String novel) {
System.out.println( name + "发布了新书《" + novel + "》!" );
lastNovel = novel;
fireEvent();
}
//触发发布新书的事件,通知所有监听这件事的监听器
private void fireEvent() {
WritertEvent writerEvent = new WritertEvent( this );
for (WriterListener writerListener : writerListenerList) {
writerListener.addNodel( writerEvent );
}
}
//提供给外部注册成为自己的监听器的方法
public void registerListener(WriterListener writerListener) {
writerListenerList.add( writerListener );
}
//提供给外部注销的方法
public void unregisterListener(WriterListener writerListener) {
writerListenerList.remove( writerListener );
}
public String getLastNovel() {
return lastNovel;
}
public String getName() {
return name;
}
}
//自定义监听器
package com.md.readerAndEvent;
import java.util.EventListener;
//自定义监听器
public interface WriterListener extends EventListener {
void addNodel(WritertEvent writerEvent);
}
//作者事件
package com.md.readerAndEvent;
import java.util.EventObject;
//作者事件
public class WritertEvent extends EventObject {
private static final long serialVersionUID = 8546459078247503692L;
public WritertEvent(Object source) {
super( source );
}
public Writers getWriter() {
return (Writers) super.getSource();
}
}
//管理类
package com.md.readerAndEvent;
import com.md.readerAndAutor.Writer;
import java.util.HashMap;
import java.util.Map;
//管理类
public class WriterManager {
private Map <String, Writers> writerMap = new HashMap <String, Writers>();
//添加作者
public void add(Writers writer) {
writerMap.put( writer.getName(), writer );
}
//根据作者姓名获取作者
public Writers getWriter(String name) {
return writerMap.get( name );
}
//单例
private WriterManager() {
}
//作者是单例的
public static WriterManager getInstance() {
return WriterManagerInstance.instance;
}
private static class WriterManagerInstance {
private static WriterManager instance = new WriterManager();
}
}
注:观察者模式:发布(release)—订阅(subscibe),变化(change)—更新(update)
事件驱动模型:请求(request)—响应(response),事件发生(occur)—事件处理(handle)
