白话-23种设计模式14-观察者模式

举报
object 发表于 2022/07/08 18:29:14 2022/07/08
【摘要】 一、白话  在网上买东西,会看到有一个价格趋势图,也会有一个按钮,写着降价通知,这样能更好的买到更便宜的东西。这就类似一种观察者模式,当一个事务的状态变更后,需要通知观察者。二、定义  定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。  Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可...

一、白话

  在网上买东西,会看到有一个价格趋势图,也会有一个按钮,写着降价通知,这样能更好的买到更便宜的东西。这就类似一种观察者模式,当一个事务的状态变更后,需要通知观察者。

二、定义

  定义对象间的一种一对多的依赖关系,当一个对象的状态发生改变时,所有依赖于它的对象都得到通知并被自动更新。

  Subject:抽象主题(抽象被观察者),抽象主题角色把所有观察者对象保存在一个集合里,每个主题都可以有任意数量的观察者,抽象主题提供一个接口,可以增                            加和删除观察者对象。
  ConcreteSubject:具体主题(具体被观察者),该角色将有关状态存入具体观察者对象,在具体主题的内部状态发生改变时,给所有注册过的观察者发送通知。
  Observer:抽象观察者,是观察者者的抽象类,它定义了一个更新接口,使得在得到主题更改通知时更新自己。
  ConcrereObserver:具体观察者,实现抽象观察者定义的更新接口,以便在得到主题更改通知时更新自身的状态。

三、示例

提供两种方案:

1.自定义观察模式

// 抽象被观察者-提供观察者新增删除等
public abstract class Subject {
    // 观察者
    protected List<Observer> observers = new ArrayList<>();

    // 新增观察者
    protected void addObserver(Observer observer) {
        this.observers.add(observer);
    }

    // 删除观察者
    protected  void delObserver(Observer observer) {
        this.observers.remove(observer);
    }

    // 通知观察者
    protected void notifyObservers(int price) {
        for (Observer observer : observers) {
            observer.update(price);
        }
    }
}
// 具体被观察者-产品
public class Product extends Subject {
    private String name ;
    private int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        if (price < this.price) {
           notifyObservers(price);
        }
        this.price = price;
    }

    public Product(String name, int price) {
        this.name = name;
        this.price = price;
    }
}

// 抽象观察者-提供观察者需要进行的操作
public abstract class Observer {
    Subject subject;
    abstract void update(int price);
}
// 具体观察者-价格商城提醒
public class PriceObserver extends Observer {

    // 添加观察者
    public PriceObserver(Subject subject) {
        this.subject = subject;
        subject.addObserver(this);
    }

    @Override
    public void update(int price) {
        System.out.println("收到护肤品降价通知,目前最新价格" + price + "元");
    }
}
public class ObserverApplication {

    // 客户端调用
    public static void main(String[] args) {
        // 产品
        Product product = new Product("护肤霜", 100);
        // 价格观察者
        PriceObserver priceObserver = new PriceObserver(product);
        // 降价
        System.out.println("==降价前==产品:" +product.getName()+",价格:"+product.getPrice());
        product.setPrice(80);
    }

}

输出结果:

==降价前==产品:护肤霜,价格:100
收到护肤品降价通知,目前最新价格80元


2.使用jdk提供的工具

主要包含两个类 java.util.Observable 抽象被观察者 java.util.Observer 抽象观察者,直接使用即可

// 具体被观察者-产品
public class Product2 extends Observable {
    private String name ;
    private int price;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getPrice() {
        return price;
    }

    public void setPrice(int price) {
        if (price < this.price) {
            setChanged();
            notifyObservers(price);
        }
        this.price = price;
    }

    public Product2(String name, int price) {
        this.name = name;
        this.price = price;
    }
}
// 具体观察者-价格商城提醒
public class PriceObserver2 implements Observer {
    @Override
    public void update(Observable subject, Object params) {
        if (params instanceof Integer) {
            System.out.println("收到护肤品降价通知,目前最新价格" + params + "元");
        }
    }
}
public class Client {
    // 客户端调用
    public static void main(String[] args) {
        // 产品
        Product2 product = new Product2("护肤霜", 200);
        // 价格观察者
        PriceObserver2 priceObserver = new PriceObserver2();
        product.addObserver(priceObserver);
        System.out.println("==降价前2==产品:" +product.getName()+",价格:"+product.getPrice());
        // 降价
        product.setPrice(180);
    }
}

输出结果:

==降价前2==产品:护肤霜,价格:200
收到护肤品降价通知,目前最新价格180元

四、总结

  特点:观察者和被观察者是抽象耦合的。容易出现死循环。通知所有观察者所以浪费过多时间

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。