java——观察者模式

观察者模式

一、什么是观察者模式

        观察者一般可以看做是第三者,比如在学校上自习的时候,大家肯定都有过交头接耳、各种玩耍的经历,这时总会有一个“放风”的小伙伴,当老师即将出现时及时“通知”大家老师来了。再比如,拍卖会的时候,大家相互叫价,拍卖师会观察最高标价,然后通知给其它竞价者竞价,这就是一个观察者模式。

        对于观察者模式而言,肯定有观察者和被观察者之分。比如在一个目录下建立一个文件,这时系统会通知目录管理器增加目录,并通知磁盘减少空间,在这里,文件就是观察者,目录管理器和磁盘就是被观察者。

        观察者模式(Observer),又叫发布-订阅模式(Publish/Subscribe),定义对象间一种一对多的依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并自动更新。UML结构图如下:
在这里插入图片描述
        其中,Subject类是主题,它把所有对观察者对象的引用文件存在了一个聚集里,每个主题都可以有任何数量的观察者。抽象主题提供了一个接口,可以增加和删除观察者对象;Observer类是抽象观察者,为所有的具体观察者定义一个接口,在得到主题的通知时更新自己;ConcreteSubject类是具体主题,将有关状态存入具体观察者对象,在具体主题内部状态改变时,给所有登记过的观察者发出通知;ConcreteObserver是具体观察者,实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协同。

二、观察者模式的应用

  1. 何时使用
  • 一个对象状态改变,所有的依赖对象都将得到通知
  1. 方法
  • 使用面向对象技术
  1. 优点
  • 观察者和被观察者是抽象耦合的
  • 建立了一套触发机制
  1. 缺点
  • 如果一个被观察者对象有很多的直接和间接的观察者的话,将所有的观察者都通知到会花费很多时间
  • 如果观察者和观察目标间有循环依赖,可能导致系统崩溃
  • 没有相应的机制让观察者知道所观察的目标对象是怎么发生变化的
  1. 使用场景
  • 关联行为场景
  • 事件多级触发场景
  • 跨系统的消息变换场景,如消息队列的处理机制

三、观察者模式的实现

1、类图

在这里插入图片描述

2、主题:Subject

package com.gykalc.jdk8.observer;

/**
 * 主题,也就是被观察者
 */
public interface Subject {
    /**
     * 添加一个观察者
     * @param observer
     */
    void addObserver(Observer observer);

    /**
     * 移除一个观察者
     * @param observer
     */
    void removeObServer(Observer observer);

    /**
     * 通知所有观察者
     */
    void notifyObServer();
}

3、抽象观察者:Observer

package com.gykalc.jdk8.observer;

/**
 * 观察者
 */
public interface Observer {
    void update(News news);
}

4、具体被观察者和被观察属性:CCTV1、News

package com.gykalc.jdk8.observer;

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

public class CCTV1 implements Subject {

    private List<Observer> observerList = new ArrayList<>();

    private News news;

    public News getNews() {
        return news;
    }

    public void setNews(News news) {
        this.news = news;
    }

    @Override
    public void addObserver(Observer observer) {
        observerList.add(observer);
    }

    @Override
    public void removeObServer(Observer observer) {
        observerList.remove(observer);
    }

    @Override
    public void notifyObServer() {
        observerList.stream().forEach(observer -> observer.update(news));
    }
}

class News {
    private String title;
    private String msg;

    public News(String title, String msg) {
        this.title = title;
        this.msg = msg;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public String getMsg() {
        return msg;
    }

    public void setMsg(String msg) {
        this.msg = msg;
    }

    @Override
    public String toString() {
        return "News{" +
                "title='" + title + '\'' +
                ", msg='" + msg + '\'' +
                '}';
    }
}

5、具体观察者:LiSi、ZhangSan、WangWu

package com.gykalc.jdk8.observer;

public class ZhangSan implements Observer {
    @Override
    public void update(News news) {
        System.out.println("张三正在看:" + news.toString());
    }
}

class LiSi implements Observer{

    @Override
    public void update(News news) {
        System.out.println("李四正在观看:" + news.toString());
    }
}

class WangWu implements Observer {
    @Override
    public void update(News news) {
        System.out.println("王五正在观看:" + news.toString());
    }
}

6、调用测试类:Client

package com.gykalc.jdk8.observer;

public class Client {
    public static void main(String[] args) {
        CCTV1 cctv1 = new CCTV1();
        LiSi liSi = new LiSi();
        ZhangSan zhangSan = new ZhangSan();
        WangWu wangWu = new WangWu();
        cctv1.addObserver(liSi);
        cctv1.addObserver(zhangSan);
        cctv1.addObserver(wangWu);

        cctv1.setNews(new News("货拉拉长沙女子跳车", ".....新闻内容....."));
        cctv1.notifyObServer();

        cctv1.setNews(new News("头条头条", ".....骗你的....."));
        cctv1.notifyObServer();
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
观察者模式是一种常见的设计模式,用于在对象之间建立一对多的依赖关系。在该模式中,一个主题(被观察者)维护了一个观察者列表,并在自身状态发生变化时通知所有观察者进行相应的更新。 以下是一个Java实现观察者模式的例子: 1.定义主题接口Subject和观察者接口Observer: ```java public interface Subject { void registerObserver(Observer observer); void removeObserver(Observer observer); void notifyObservers(); } public interface Observer { void update(); } ``` 2.实现具体的主题类ConcreteSubject: ```java import java.util.ArrayList; import java.util.List; public class ConcreteSubject implements Subject { private int state; private List<Observer> observers = new ArrayList<>(); public int getState() { return state; } public void setState(int state) { this.state = state; notifyObservers(); } @Override public void registerObserver(Observer observer) { observers.add(observer); } @Override public void removeObserver(Observer observer) { observers.remove(observer); } @Override public void notifyObservers() { for (Observer observer : observers) { observer.update(); } } } ``` 3.实现具体的观察者类ConcreteObserver: ```java public class ConcreteObserver implements Observer { private int observerState; private ConcreteSubject subject; public ConcreteObserver(ConcreteSubject subject) { this.subject = subject; this.subject.registerObserver(this); } @Override public void update() { observerState = subject.getState(); System.out.println("Observer state updated: " + observerState); } } ``` 4.使用观察者模式: ```java public class ObserverPatternDemo { public static void main(String[] args) { ConcreteSubject subject = new ConcreteSubject(); ConcreteObserver observer1 = new ConcreteObserver(subject); ConcreteObserver observer2 = new ConcreteObserver(subject); subject.setState(1); subject.setState(2); } } ``` 输出结果为: ``` Observer state updated: 1 Observer state updated: 1 Observer state updated: 2 Observer state updated: 2 ```
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值