java 观察者模式_架构轻松学--JAVA“观察者模式”

引子

观察者模式是设计模式中行为模式的一种,在我们的日常编程中可能使用并不频繁,但却是各大技术和中间件中经常涉足的一个模式,设计上更显得高大上。比如NIO、JMS、Vue.js、Spring Cloud等,都用到了观察者模式或其思路。下面我们来详细学习它。

场景

某家科技公司目前在开发一个项目,设计小组需要上报项目的进度给部门经理,主要有包括更新原有的业务模块进度和添加新业务的模块完成进度。那么部门经理需要什么途径能最快的得到进度的信息呢?或者可能是项目总监也想去获取到最新的进展情况呢?我们该如何去处理呢?

很多时候我们就会想到继承去解决这一情况,毕竟面向对象思想时刻影响这一我们,但是如果某天项目经理出差了,他不想看项目进度了,那我们又改怎么办呢?

我们能不能就是设计一个业务,让能想知道该进度的人,不管什么时候,只要有开发者上报进度的时候就一下他就得到进度的信息,而他无需去关心这个过程。

你是否能想到合适的解决方案呢?当然就是观察者。

含义

什么是观察者模式?

观察者模式定义一系列对象之间的一对多关系,当一个对象改变、更新状态时,依赖它的都会收到通知改变或者更新。

为什么需要观察者模式?

从定义中我们可以知道观察者模式当对象改变时,其他依赖的对象都会收到改变信息的状态。

从本例分析项目经理想知道进度情况,他只需要绑定进度,他就可以知道进度信息了,而无需关心如何操作,如果再增加一个想知道进度的人呢?也很容易,也让他绑定进度信息数据就好了,不想知道的时候就解除绑定,就不在获取进度信息了。

如何实现观察者模式?

自定义观察者模式

我们先来看一下这个UML类图进行分析

b0eadb3da332bf882b571ce25545e62f.png

具体实现步骤

1.构造一个主题Subject或者是一个被观察者Observeable,这是一个接口或者是抽象类

 public interface Subject { //注册观察者 void registerObserver(Observer observe); //解除绑定观察者 void unRegisterObserver(Observer observe); //更新数据 void notifyObservers(); }

2.构建一个被观察者的实现,DevelopmentProgressData
registerObserver(Observer o);//方法中将观察者添加到注册列表中
unRegisterObserve(Observer o);//删除观察者

public class DevelopmentProgressData implements Subject { private ArrayList arrayObserve; private int completeProgress;//完成进度 private int updateProgress;//更新进度 public DevelopmentProgressData() { arrayObserve = new ArrayList(); } @Override public void registerObserver(Observer observer) { //将观察者添加到列表中 arrayObserve.add(observer); } @Override public void unRegisterObserver(Observer observer) { int i = arrayObserve.indexOf(observer); if (i >= 0) { //将观察者从列表中解除 arrayObserve.remove(i); } } //通知所以观察者数据更新了 @Override public void notifyObservers() { for (int i = 0; i < arrayObserve.size(); i++) { Observer o = (Observer) arrayObserve.get(i); o.update(completeProgress, updateProgress); } }  //更新数据 public void setCurrentData(int completeProgress, int updateProgress){ this.completeProgress = completeProgress; this.updateProgress = updateProgress; notifyObservers }}

3.创建一个观察者接口Observer

 public interface Observer { //更新数据 void update(int completeProgress, int updateProgress); }

4.构建具体的观察者实现(相当于上面例子的项目经理),需实现接口Observes,
将主题Subject通过构造函数传入并向其注册观察者,如 ProductManagerObserver
调用 developmentProgressSubject.registerObserver(this);将观察者注册到观察列表中

public class ProductManagerObserver implements Observer { private int completeProgress;//完成进度 private int updateProgress;//更新进度 //将主题当成观察者的属性 private Subject developmentProgressSubject; public ProductManagerObserver(Subject developmentProgressSubject) { this.developmentProgressSubject = developmentProgressSubject; //注册该观察者 developmentProgressSubject.registerObserver(this); } @Override public void update(int completeProgress, int updateProgress) { this.completeProgress = completeProgress; this.updateProgress = updateProgress; }}

测试

public class RunTest { public static void main(String[] args) { Subject developmentProgressData = new DevelopmentProgressData(); Observer productManagerObserver = new ProductManagerObserver(developmentProgressData); Observer projectManagerObserver = new ProjectManagerObserver(developmentProgressData); //更新数据并通知观察者,产品经理和项目经理均可获得信息 developmentProgressData.setCurrentData(34, 45); //当项目经理出差了,不观察项目进度了就取消订阅了 developmentProgressData.unRegisterObserver(projectManagerObserver); //更新数据并通知观察者,当前只有产品经理科获取信息 developmentProgressData.setCurrentData(46, 90); }}

输出结果

产品经理管理者显示当前数据 完成进度为: 34更新修改进度为:45项目管理真显示当前数据完成进度为: 34更新修改进度为:45产品经理管理者显示当前数据 完成进度为: 46更新修改进度为:90

根据java.util.observable实现观察者模式

具体实现步骤

1.首先观察者需要实现java.util.Observer,然后将其被观察者java.util.Observable传入其观察者的构造中

public class BossMngObserver implements Observer { private Observable observable; private int valuableProductNum; //库存有贵重产品 private int normalProductNum; //普通产品 public BossMngObserver(Observable observable) { this.observable = observable; //通过observerable.addObserver(this)添加观察者 observable.addObserver(this); } //实现 Observer更新数据方法 @Override public void update(Observable o, Object arg) { if (o instanceof InventoryData) { InventoryData inventoryData = (InventoryData) o; this.valuableProductNum = inventoryData.getValuableProductNum(); this.normalProductNum = inventoryData.getNormalProductNum(); } }}

2.被观察者需要继承java.util.Observerable

 public class InventoryData extends Observable { private int valuableProductNum; //库存有贵重产品 private int normalProductNum; //普通产品 public void setCurrentData(int valuableProductNum, int normalProductNum) { this.valuableProductNum = valuableProductNum; this.normalProductNum = normalProductNum; //调用notifyObserves()更新数据 setChanged(); notifyObservers(); } }

测试

3.Test.class

public class Test { public static void main(String[] args) { //创建被观察者 InventoryData inventoryData = new InventoryData(); //创建观察者 ValuableInfoMngObserver io = new ValuableInfoMngObserver(inventoryData); //io.deleteObserve(); //更新数据通知观察者 inventoryData.setCurrentData(20, 30); //创建观察者 NormalInfoMngObserver no = new NormalInfoMngObserver(inventoryData); //no.deleteObserver(); //更新数据通知观察者 inventoryData.setCurrentData(15, 27); //创建观察者 BossMngObserver bossMngObserver = new BossMngObserver(inventoryData);//更新数据通知观察者 inventoryData.setCurrentData(10, 50); }}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值