【设计模式】观察者模式

  |   0 评论   |   147 浏览

简介

定义了对象之间的一对多依赖,让多个观察者对象同时监听某一个主题对象,当主题对象发生变化时,它的所有观察者都会收到通知并更新,定义一个Subject类和Observer类,如果Subject的状态更新Observer类可以接收到消息并自动更新,属于行为型。

适用场景

1、关联行为场景,建立一套触发机制
2、应该定义对象之间的一对多依赖关系,而不是使对象紧密耦合
3、应该确保当一个对象发生更改时,自动更新依赖对象

优点

1、观察者和被观察者之间建立一个抽象的耦合
2、观察者模式支持广播通信

缺点

1、观察者之间有过多的细节依赖,提高时间消耗及程序复杂度
2、使用的得当,要避免循环调用

代码示例

image.png
厨师类-主题类

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("番茄炒蛋");
    }
}

也可以关注我的公众号:程序之声
图片
关注公众号,领取更多资源

本文为博主原创文章,未经博主允许不得转载。

评论

发表评论