网站服务器的作用和功能有哪些,山东饰品行业网站开发,定制家具十大品牌,大理做网站目录 场景
代码示例
定义
观察者模式的优缺点
本质
何时选用
简单变型-区别对待观察者 场景
我是一家报社#xff0c;每当我发布一个新的报纸时#xff0c;所有订阅我家报社的读者都可以接收到
代码示例
报纸对象
package day11观察者模式;import java.util.Observ…目录 场景
代码示例
定义
观察者模式的优缺点
本质
何时选用
简单变型-区别对待观察者 场景
我是一家报社每当我发布一个新的报纸时所有订阅我家报社的读者都可以接收到
代码示例
报纸对象
package day11观察者模式;import java.util.Observable;/*** 报纸对象*/
public class NewsPaper extends Observable {/*** 报纸的内容*/private String content;/*** 获取报纸的具体内容* return 报纸的具体内容*/public String getContent() {return content;}/*** 示意设置报纸的具体内容相当于要出版报纸了* param content 报纸的具体内容*/public void setContent(String content) {this.content content;// 内容有了说明又出新报纸了那就通知所有的读者this.setChanged();// 然后主动通知用的推的方式this.notifyObservers(this.content);// 如果用拉的方式这么调用
// this.notifyObservers();}
}读者也就是观察者
package day11观察者模式;import java.util.Observable;
import java.util.Observer;/*** 真正的读者也就是观察者*/
public class Reader implements Observer {/*** 读者的姓名*/private String name;public String getName() {return name;}public void setName(String name) {this.name name;}Overridepublic void update(Observable o, Object arg) {// 这里采用推的方式System.out.println(name 收到报纸了,进行阅读。目标推过来的内容是 arg);// 这里是获取拉的数据
// System.out.println(name 收到报纸了进行阅读。主动到目标对象去拉的内容是 ((NewsPaper)o).getContent());}
}client
package day11观察者模式;/*** 客户端使用*/
public class Client {public static void main(String[] args) {// 1.创建一个报纸作为被观察者NewsPaper subject new NewsPaper();// 2.创建阅读者也就是观察者Reader reader1 new Reader();reader1.setName(张三);Reader reader2 new Reader();reader2.setName(李四);Reader reader3 new Reader();reader3.setName(王五);// 3.注册阅读者subject.addObserver(reader1);subject.addObserver(reader2);subject.addObserver(reader3);// 4.要出报纸啦subject.setContent(本期内容是观察者模式);}
}解析
报社就是一个发布者读者就是一个个订阅者发布者提供订阅方法每次发布者发布新的东西时就会通知订阅者这条新的消息。
报社NewsPaper它继承了Observable类这个类包含了注册方法提示改变通知方式推和拉等方法,NewsPaper包含了报纸内容对象get方法就不说了set时会进行提示改变了并主动通知用的推的方式。
观察者Reader它实现了Observer接口实现了update方法java实现观察者模式时默认是拉模型如果使用推模型那么在update这个方法里通过推拉的获取方式都可以获取到值 定义 类似发布订阅模式
观察者模式的优缺点 本质
观察者模式的本质触发联动
在程序运行期间通过这样的联动可以控制观察者在update执行的时候。
何时选用 简单变型-区别对待观察者
举例根据水质污染的严重程度来分别告知不同的管理者 思路将水质污染当作被观察的目标监测员、预警人员和领导就是观察者。在目标里面进行判断满足就通知不满足不通知。
观察者接口
1.被通知的方法2.设置观察人员的职务3.获取观察人员的职务
package day11观察者模式.高级;/*** 水质观察者接口定义*/
public interface WatcherObserver {/*** 被通知的方法* param subject 传入被观察的目标对象*/public void update(WaterQualitySubject subject);/*** 设置观察人员的职务* param job*/public void setJob(String job);/*** 获取观察人员的职务* return*/public String getJob();}观察者的具体实现
package day11观察者模式.高级;public class Watcher implements WatcherObserver{private String job;Overridepublic void update(WaterQualitySubject subject) {// 这里采用拉的方式System.out.println(job 获取到通知当前污染级别为 subject.getPolluteLevel());}Overridepublic void setJob(String job) {this.job job;}Overridepublic String getJob() {return job;}
}目标的父对象(抽象类) 1.定义抽象是因为我们不需要全部都发消息所以让子类去根据业务的实际需要自己去选择性的通知。2.而且在我们传入目标对象的时候具有很好的封装性不需要对外展示具体的目标对象传给观察者的只是目标的父抽象类。 package day11观察者模式.高级;import java.util.ArrayList;
import java.util.List;/*** 定义目标的父对象*/
public abstract class WaterQualitySubject {/*** 用来保存注册的观察者对象*/protected ListWatcherObserver observers new ArrayListWatcherObserver();/*** 注册观察者对象* param observer 观察者对象*/public void attach(WatcherObserver observer){observers.add(observer);}/*** 删除观察者对象* param observer*/public void detach(WatcherObserver observer){observers.remove(observer);}/*** 通知对应的观察者对象*/public abstract void notifyWatchers();/*** 获取水质污染的级别*/public abstract int getPolluteLevel();
}目标的实现(继承目标父抽象类)
package day11观察者模式.高级;/*** 具体的检测对象*/
public class WaterQuality extends WaterQualitySubject{/*** 污染的级别0正常 1轻度污染 2中度污染 3高度污染*/private int polluteLevel 0;/*** 获取水质污染的级别* return*/Overridepublic int getPolluteLevel() {return polluteLevel;}/*** 当检测水质情况后设置水质污染的级别* param polluteLevel 水质污染的级别*/public void setPolluteLevel(int polluteLevel) {this.polluteLevel polluteLevel;// 通知相应的观察者this.notifyWatchers();}/*** 通知相应的观察者对象*/Overridepublic void notifyWatchers() {// 循环所有注册的观察者for (WatcherObserver watcher : observers) {// 开始根据污染级别判断都通知谁if (this.polluteLevel 0 ){// 通知监测员做记录if (监测人员.equals(watcher.getJob())){watcher.update(this);}}if (this.polluteLevel 1 ){// 通知监测员做记录if (预警人员.equals(watcher.getJob())){watcher.update(this);}}if (this.polluteLevel 2 ){// 通知监测员做记录if (领导.equals(watcher.getJob())){watcher.update(this);}}}}}client
package day11观察者模式.高级;public class Client {public static void main(String[] args) {// 创建具体的检测对象WaterQuality subject new WaterQuality();// 创建几个观察者Watcher watcher1 new Watcher();watcher1.setJob(监测人员);Watcher watcher2 new Watcher();watcher2.setJob(预警人员);Watcher watcher3 new Watcher();watcher3.setJob(领导);// 注册观察者subject.attach(watcher1);subject.attach(watcher2);subject.attach(watcher3);// 填写水质报告System.out.println(水质正常---);subject.setPolluteLevel(0);System.out.println(轻度污染---);subject.setPolluteLevel(1);System.out.println(重度污染---);subject.setPolluteLevel(2);}
}解析
从client开始先创建了具体的检测对象 他有什么用呢可以注册观察者可以发布通知
创建了几个观察者实现对象给他们赋予了不同的职务。
将观察者跟目标对象进行关联也就是注册点进去看一下调用了attach方法这个方法不是具体的检测对象本身的而是它的抽象父类中的方法 都注册进去之后目标对象开始运行他现在出了一个水质为0的污染报告这个时候应该传递给谁信息呢 点进这个setPolluteLevel(0)看一下 。这个是具体的检测对象本身的方法。 可以看出首先将传过来的值赋值给当前对象然后调用了 this.notifyWatchers()方法。我们接着往下。 进来这个方法后遍历所有注册到目标对象的观察者(订阅了该目标对象的订阅者)这个observers哪里来的,是注册而来的。
接着判断属于哪一类的污染此时过来的污染为0就判断当前观察者的职务是不是检测人员如果是就调用update更新的方法如果不是就不用管。
我们看一下update被通知方法的接口 接下来看看它的实现 解析判断是不是检测人员如果是我就给他发送消息它就能接收到消息。
如果污染为1那么就满足两个条件就会给预警人员和检测人员都发送消息