观察者模式学习

观察者(Observer)模式的定义:指多个对象间存在一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。这种模式有时又称作发布-订阅模式、模型-视图模式,它是对象行为型模式。
其UML图如下:
在这里插入图片描述
下面以在工作中同事摸鱼,当老板回来时,前台通知同事停止摸鱼,继续工作为例子来说明观察者模式。
涉及的角色:

  1. 抽象通知者
  2. 具体通知者(主题)
  3. 抽象观察者
  4. 具体观察者(订阅者)

抽象通知者:

/**
 * 主体类或者抽象通知者
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public abstract class Subject {
    // 通知者名称
    protected String name;
    // 通知者状态
    protected String subjectState;
    // 通知的内容
    protected String content;

    // 新增
    public abstract void addObserver(Observer observer);

    // 移除
    public abstract void removeObserver(Observer observer);

    // 通知行为
    public abstract void notifyMsg();
}

具体通知者:

/**
 * 具体通知者(前台)
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class ConcreteSubject extends Subject{
    // 观察者列表
    private List<Observer> observers = new ArrayList<>();

    public ConcreteSubject(String name, String subjecState, String content){
        super.name = name;
        super.subjectState = subjecState;
        super.content = content;
    }

    // 新增
    @Override
    public void addObserver(Observer observer){
        observers.add(observer);
    }

    // 移除
    @Override
    public void removeObserver(Observer observer){
        observers.remove(observer);
    }

    // 通知行为
    @Override
    public void notifyMsg(){
        for (Observer observer : observers) {
            observer.update();
        }
    }
}

抽象观察者:

/**
 * 抽象观察者
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public abstract class Observer {

    //观察者名称
    protected String name;
    //通知者
    protected Subject subject;

    // 观察者的行为
    public abstract void update();

    // 移除使用
    @Override
    public boolean equals(Object obj) {
        return obj.equals(name);
    }
}

具体观察者1号:

/**
 * 具体观察者1号 在摸鱼看直播
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class ConcreteObserver01 extends Observer{

    public ConcreteObserver01(String name, Subject subject) {
        super.name = name;
        super.subject = subject;
    }

    @Override
    public void update() {
        System.out.println(subject.name + " " + subject.subjectState + " " + subject.content + " " + super.name + " 停止观看NBA直播,继续工作!");
    }
}

具体观察者2号:

/**
 * 具体观察者2号 在摸鱼看股票
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class ConcreteObserver02 extends Observer{

    public ConcreteObserver02(String name, Subject subject) {
        super.name = name;
        super.subject = subject;
    }

    @Override
    public void update() {
        System.out.println(subject.name + " " + subject.subjectState + " " + subject.content + " " + super.name + " 停止观看股票,继续工作!");
    }
}

测试:

/**
 * @author Linging
 * @version 1.0.0
 * @since 1.0
 */
public class Main {

    /**
     * 观察者模式
     * 1.抽象通知者 Subject
     * 2.具体通知者 ConcreteSubject
     * 3.抽象观察者 Observer
     * 4.具体观察者 ConcreteObserver01、ConcreteObserver02....
     *
     * 同事摸鱼,老板回来,前台通知同事停止摸鱼,继续工作
     * @param args
     */
    public static void main(String[] args) {
        // 具体通知者|主题 前台
        Subject subject = new ConcreteSubject("前台", "高度警惕", "boss回来了");

        // 具体观察者|订阅者
        Observer observer01 = new ConcreteObserver01("张三", subject);
        Observer observer02 = new ConcreteObserver02("李四", subject);

        subject.addObserver(observer01);
        subject.addObserver(observer02);

        // 由于李四跟前台的关系不好,所以前台把李四从观察者列表剔除,导致李四没有收到通知,哈哈
        subject.removeObserver(observer02);

        // 通知
        subject.notifyMsg();
    }
}

在这里插入图片描述

观察者模式总结:
优点:

  • 降低了目标与观察者之间的耦合关系,两者之间是抽象耦合关系。符合依赖倒置原则。
  • 目标与观察者之间建立了一套触发机制。

缺点:

  • 目标与观察者之间的依赖关系并没有完全解除,而且有可能出现循环引用。
  • 当观察者对象很多时,通知的发布会花费很多时间,影响程序的效率。
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值