简介
定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新,定义一个Subject类和Observer类,如果Subject的状态更新Observer类可以接收到消息并自动更新,属于行为型。
适用场景
1、关联行为场景,建立一套触发机制
2、应该定义对象之间的一对多依赖关系,而不是使对象紧密耦合
3、应该确保当一个对象发生更改时,自动更新依赖对象
优点
1、观察者和被观察者之间建立一个抽象的耦合
2、观察者模式支持广播通信
缺点
1、观察者之间有过多的细节依赖,提高时间消耗及程序复杂度
2、使用的得当,要避免循环调用
代码示例
厨师类-主题类
public class Cook extends Observable {
private String name;
public Cook(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void burnGreens(String greens){
setChanged();
notifyObservers(greens);
}
}
服务员类-观察者
public class Waiter implements Observer {
private String name;
public Waiter(String name) {
this.name = name;
}
@Override
public void update(Observable o, Object arg) {
String greens = (String)arg;
Cook cook = (Cook)o;
System.out.println(cook.getName()+"厨师烧了一个"+greens+","+this.name+"准备上菜");
}
}
测试类
public class ObserverTest {
public static void main(String[] args) {
Cook cook = new Cook("李四");
Waiter waiter1 = new Waiter("服务员1");
Waiter waiter2 = new Waiter("服务员2");
cook.addObserver(waiter1);
cook.addObserver(waiter2);
cook.burnGreens("番茄炒蛋");
}
}
输出结果为:
李四厨师烧了一个番茄炒蛋,服务员2准备上菜
李四厨师烧了一个番茄炒蛋,服务员1准备上菜
源码分析
jdk中应用
Event、AWTEvent都是事件通知,当按钮被点击的时候就会触发事件。
servlet中应用
ServletRequestListener
是对请求的一个监听,如果有请求过来,就会调用requestInitialized
方法,如果请求结束那么会调用requestDestroyed
方法
guava中应用
在guava中,封装了观察者模式,使用@Subscribe
注解来表示观察者,EventBus就是主题类,
被观察者
public class GuavaCook {
private EventBus eventBus = new EventBus();
public GuavaCook() {
}
public void register(Object obj){
eventBus.register(obj);
}
public void unregister(Object obj){
eventBus.unregister(obj);
}
public void doneGreens(Object obj){
eventBus.post(obj);
}
}
观察者
public class GuavaWaiter {
@Subscribe
public void servingGreens(Object obj){
System.out.println(obj+"准备上菜");
}
}
测试类
public class GuavaTest {
public static void main(String[] args) {
GuavaWaiter guavaWaiter = new GuavaWaiter();
GuavaCook guavaCook = new GuavaCook();
guavaCook.register(guavaWaiter);
guavaCook.doneGreens("番茄炒蛋");
}
}
本文为博主原创文章,未经博主允许不得转载。
更多内容请访问:IT源点
注意:本文归作者所有,未经作者允许,不得转载