Bootstrap

JAVA设计模式-观察者模式

概述:

观察者模式通常由两个对象组成:观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应,所以也被称作“发布-订阅模式”。

特点:

  • 优点:

    解耦且可以在程序运行时动态增加或删除观察者对象。开放封闭原则,如果要添加一个观察者只需要新增一个观察者对象就可以

  • 缺点:
    当动态创建一个观察者过多,没有被正确移除时会导致内存泄露的异常。
    循环依赖问题(可使用弱实体、依赖注入容器解决)

组成:

抽象被观察者》具体被观察者》抽象观察者》具体观察者

应用场景:

  • 生活:

    1、粉丝(观察者)和博主(被观察者)。博主发布一条博客或者文章,然后通知给说所有粉丝。
    2、共享单车(被观察者)和用户(观察者)。当有新的共享单车被租用时,系统会发送通知给用户。

  • 程序:

    1、当一个对象的状态发生改变时,需要通知多个对象作出响应。例如,软件更新前,会通知所有用户需要更新的时间
    2、当很对对象同事对某一个主题感兴趣时,可以拆用观察者模式实现发布订阅模式。例如生产者发送消息到消息队列中,并通知所有订阅此队列的消费者进行消费。

UML图:

在这里插入图片描述

代码示例:

/**
 * 被观察者抽象
 */
interface Subscribe {
    void addObserve(Observer observer);

    void removeObserve(Observer observer);

    void notifyObserve(String name);
}

/**
 * 观察者抽象
 */
interface Observer {
    void shopping(String name);
}

/**
 * 被观察者具体 商城
 */
class Mall implements Subscribe{
    List<Observer> observers = new ArrayList<>();
    @Override
    public void addObserve(Observer observer) {
        observers.add(observer);
    }
    @Override
    public void removeObserve(Observer observer) {
        observers.remove(observer);
    }
    @Override
    public void notifyObserve(String name){
        observers.forEach(e->{
            e.shopping(name);
        });
    }

}

/**
 * 观察者具体
 */
class Client implements Observer{
    String userName;
    @Override
    public void shopping(String name) {
        System.out.println(userName + "抢购商品:" + name);
    }
    public Client(String userName) {
        this.userName = userName;
    }
}

@org.junit.Test
public void test(){
    Client zhangShan = new Client("张三");
    Client liSi = new Client("李四");
    Client wangWu = new Client("王五");
    Mall mall = new Mall();
    mall.addObserve(zhangShan);
    mall.addObserve(liSi);
    mall.addObserve(wangWu);
    mall.notifyObserve("波司登羽绒服");

}
结果:
张三抢购商品:波司登羽绒服
李四抢购商品:波司登羽绒服
王五抢购商品:波司登羽绒服
;