Java设计模式—观察者(Observer)

本文详细介绍了观察者模式的概念及其在Java中的实现方式,通过购房场景的例子展示了如何利用观察者模式来建立主题与观察者之间的依赖关系。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

观察者模式的定义:

观察者模式定义了一种一对多的依赖关系,被观察者一般称为主题,一个主题对象会有多个观察者,一旦主题更新了信息,就会推送到各个观察者处。
举一个生活中常见的例子:

这里写图片描述

3个人(观察者)都想买房(主题对象),于是他们都订阅了某楼盘的房价信息,一旦楼盘的房价变动,这3个人都会受到最新的房价。这就是观察者模式的作用。

其实Java中,已经内置有实现观察者模式的api。但我们先来自己实现观察者模式。

自行实现观察者模式

观察者模式的组成

  • 抽象主题角色:抽象主题提供一个接口,可以增加和删除观察者角色。

  • 具体主题角色:当具体主题内部的信息更新时,通知所有注册的观察者,使他们收到消息

  • 抽象观察者角色:为所有具体的观察者定义一个接口,在得到主题的通知时更新自己。

  • 具体观察者角色:该角色实现抽象观察者角色所要求的更新接口。

下面是具体的实例(该实例以购房为情景)
首先看工程目录图:
这里写图片描述

抽象主题角色:

public interface Subject {

    // 添加主题(被观察者)
    public void addObserver(Observer observer);

    // 移除主题(被观察者)
    public void removeObserver(Observer observer);

    // 更新所有观察者
    public void notifyObserver();
}

具体主题角色:

public class House implements Subject {

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

    private float price;

    public House(float price){
        this.price = price;
    }

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

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

    @Override
    public void notifyObserver() {
        if(observers != null){
            for(Observer observer : observers){
                observer.update(price);
            }
        }
    }

    public void updatePrice(float price){
        this.price = price;
        notifyObserver();
    }

    public String toString(){
        return "房价为:" + price;
    }
}

抽象观察者角色:

public interface Observer {

    public void update(float price);
}

具体观察者角色:

public class HouseObserver implements Observer{

    private String observerName;

    //为不同的房子价格观察者记录名字
    public HouseObserver(String observerName){
        this.observerName= observerName;
    }

    @Override
    public void update(float currentPrice) {
        System.out.println( observerName+ " 观察到当前的价格为:" + currentPrice);
    }

}

测试代码

public class testObserver {
    public static void main(String args[]){
        //设置初始价格
        House house = new House(10000);

        HouseObserver observer1 = new HouseObserver("买房者A");
        HouseObserver observer2 = new HouseObserver("买房者B");
        HouseObserver observer3 = new HouseObserver("买房者C");

        //加入观察者观察房价
        house.addObserver(observer1);
        house.addObserver(observer2);
        house.addObserver(observer3);

        //初始房价
        System.out.println(house);
        //更新房价
        house.updatePrice(6666);
        //更新后房价
        System.out.println(house);
    }
}

下面是运行的结果:

房价为:10000.0
买房者A 观察到当前的价格为:6666.0
买房者B 观察到当前的价格为:6666.0
买房者C 观察到当前的价格为:6666.0
房价为:6666.0

具体的解释都在代码中,也不一一解释了。
关键在于 —–> house.updatePrice(6666) 主题更新,每一个买房者都接收到了通知,并且打印了出来。

Java内置观察者模式

Java中提供了一个Observerable类Observer接口,这两个类就相当于上面所提到的 抽象主题角色抽象观察者角色

需要注意的地方:

  1. Observerable是一个类,Observer是一个接口,所有具体主题角色都要继承Observerable,所有juice观察者角色都要实现Observer接口。
  2. 具体主题角色信息改变了,它必须调用setChanged()方法。
  3. 具体主题角色准备通知观测程序它的改变时,它必须调用notifyObservers()方法,这导致了在观测对象中对update()方法的调用。

下面来看具体的实例(也是基于购房实例)

工程结构:
这里写图片描述

具体主题角色:

public class House extends Observable {

    private float price;

    public House(float price) {
        this.price = price;
    }

    public float getPrice() {
        return price;
    }

    public void setPrice(float price) {

        // 标记已经变化
        super.setChanged();
        // 设这价格被改变
        super.notifyObservers(price);
        // 更新价格
        this.price = price;

    }

    public String toString() {
        return "房价为:" + price;
    }
}

具体观察者角色:

public class HouseObserver implements Observer {

    private String houseName;

    // 为不同的房子价格观察者记录名字
    public HouseObserver(String houseName) {
        this.houseName = houseName;
    }

    @Override
    public void update(Observable subject, Object price) {
        if (price instanceof Float) {
            float currentPrice = (Float) price;
            System.out.println(houseName + "  观察到当前的价格为:" + currentPrice);
        }
    }

}

测试代码

public class testObserver {
    public static void main(String args[]) {
        // 设置初始价格
        House house = new House(10000);

        HouseObserver observer1 = new HouseObserver("买房者A");
        HouseObserver observer2 = new HouseObserver("买房者B");
        HouseObserver observer3 = new HouseObserver("买房者C");

        // 加入观察者观察房价
        house.addObserver(observer1);
        house.addObserver(observer2);
        house.addObserver(observer3);

        // 初始房价
        System.out.println(house);
        // 更新房价
        house.setPrice(6666);
        // 更新后房价
        System.out.println(house);
    }
}

运行结果如下:

房价为:10000.0
买房者C  观察到当前的价格为:6666.0
买房者B  观察到当前的价格为:6666.0
买房者A  观察到当前的价格为:6666.0
房价为:6666.0

说明观察者模式确实起到了作用。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值