概述:
观察者模式通常由两个对象组成:观察者和被观察者。当被观察者状态发生改变时,它会通知所有的观察者对象,使他们能够及时做出响应,所以也被称作“发布-订阅模式”。
特点:
-
优点:
解耦且可以在程序运行时动态增加或删除观察者对象。开放封闭原则,如果要添加一个观察者只需要新增一个观察者对象就可以
-
缺点:
当动态创建一个观察者过多,没有被正确移除时会导致内存泄露的异常。
循环依赖问题(可使用弱实体、依赖注入容器解决)
组成:
抽象被观察者》具体被观察者》抽象观察者》具体观察者
应用场景:
-
生活:
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<>();@Overridepublic void addObserve(Observer observer) {observers.add(observer);}@Overridepublic void removeObserve(Observer observer) {observers.remove(observer);}@Overridepublic void notifyObserve(String name){observers.forEach(e->{e.shopping(name);});}}/*** 观察者具体*/
class Client implements Observer{String userName;@Overridepublic 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("波司登羽绒服");}
结果:
张三抢购商品:波司登羽绒服
李四抢购商品:波司登羽绒服
王五抢购商品:波司登羽绒服