设计模式之观察者模式

定义:

对象之间存在一对多或者一对一依赖,当一个对象改变状态,依赖它的对象会收到通知并自动更新。
MQ其实就属于一种观察者模式,发布者发布信息,订阅者获取信息,订阅了就能收到信息,没订阅就收不到信息。

优点:

1、观察者和被观察者是抽象耦合的。
2、建立一套触发机制。

缺点:

1、如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间。
2、如果在观察者和观察目标之间有循环依赖的话,观察目标会触发它们之间进行循环调用,可能导致系统崩溃。(例如:A变化了要通知B,B变化了通知A,如果程序中控制不当的话,A改变导致了B改变,就会陷入无限的死循环,进而导致系统崩溃)。

例如:吃饭时间和睡觉时间到了 闹钟工作

import java.util.ArrayList;
import java.util.List;

/**
 * 闹钟类:提醒,吃饭时间到了会提醒,睡觉时间到了也会提醒
 */
public class Clock {

    private List<AbstrackInfo> infos = new ArrayList<AbstrackInfo>();


    public void info(){
        System.out.println("闹钟通知");
        //通知
        update();
    }

    public void addInfo(AbstrackInfo info){
        infos.add(info);
    }
    //通知
    public void update(){
        for (AbstrackInfo info : infos) {
            boolean work = info.work(true);
            info.message(work);
        }
    }

    public static void main(String[] args) {
        Clock clock = new Clock();
        AbstrackInfo eat = new EatInfo();
        AbstrackInfo sp = new SleepInfo();

        clock.addInfo(eat);
        clock.addInfo(sp);

        clock.info();
    }


}

吃饭通知类

/**
 * 吃饭类
 */
public class EatInfo extends AbstrackInfo{
    boolean isEat;

    @Override
    void message(boolean isEat) {
        if(isEat){
            System.out.println("该吃饭了");
        }
    }

    @Override
    boolean work(boolean flag) {
        this.isEat = flag;
        return isEat;
    }


}

睡觉通知类

/**
 * 睡觉类
 */
public class SleepInfo extends AbstrackInfo{
    boolean isSleep;

    @Override
    void message(boolean isSleep) {
        if(isSleep){
            System.out.println("该睡觉了");
        }
    }

    @Override
    boolean work(boolean flag) {
        this.isSleep = flag;
        return isSleep;
    }


}

抽象父类

public abstract class AbstrackInfo {

    //被监听的对象
    private Clock clock;

    abstract void message(boolean flag);

    abstract boolean work(boolean flag);
}

这里,事实上还可以实现吃饭提醒类,和睡觉提醒类对闹钟的提示。例如到了某个时间,吃饭提醒类会调用闹钟去。或者发送消息提醒,都是可以的。

Spring观察者模式

ApplicationContext 事件机制是观察者设计模式的实现,通过 ApplicationEvent 类和 ApplicationListener 接
口,可以实现 ApplicationContext 事件处理。
如果容器中有一个 ApplicationListener Bean ,每当 ApplicationContext 发布 ApplicationEvent 时,
ApplicationListener Bean 将自动被触发。这种事件机制都必须需要程序显示的触发。
其中spring有一些内置的事件,当完成某种操作时会发出某些事件动作。比如监听 ContextRefreshedEvent 事件,
当所有的bean都初始化完成并被成功装载后会触发该事件,实现
ApplicationListener 接口可以收到监听动作,然后可以写自己的逻辑。
同样事件可以自定义、监听也可以自定义,完全根据自己的业务逻辑来处理。

对象说明:
1、ApplicationContext容器对象
2、ApplicationEvent事件对象(ContextRefreshedEvent容器刷新事件)
3、ApplicationListener事件监听对象

ApplicationContext事件监听

当ApplicationContext内的Bean对象初始化完成时,此时可以通过监听 ContextRefreshedEvent 得到通知。

 //监听触发执行
    @Override
    public void onApplicationEvent(ApplicationEvent applicationEvent) {
        System.out.println("我听到了!");
    }

当我们初始化的时候

 ApplicationContext act = new ClassPathXmlApplicationContext("spring-event.xml");

就会打印 我听到了!

自定义监听事件

我们这里来监听一下,虎弟什么时候会呐喊独立宣言。

public class Tiger extends ApplicationEvent {
    public Tiger(Object source) {
        super(source);
        System.out.println(source.toString());

    }
}
public class TigerListener implements ApplicationListener<Tiger> {
    @Override
    public void onApplicationEvent(Tiger tiger) {
        System.out.println("我是个伞兵!!!");
    }
}
 public static void main(String[] args) {
        ApplicationContext act = new ClassPathXmlApplicationContext("spring-event.xml");

        //添加一个自定义事件
        act.publishEvent(new Tiger("OK!兄弟们!全体目光向我看齐,看我看我,我宣布个事!!!"));
    }

整活结果是:
OK!兄弟们!全体目光向我看齐,看我看我,我宣布个事!!!
我是个伞兵!!!

nice,这里我们只触发了虎弟事件,这就实现了自定义监听事件。

本人才疏学浅,如有遗漏请大神指出,技术交流可私信,大家每天进步一点点.
这里给大家拜个早年了! @w@

  • 6
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值