文章来源:软件秘笈--设计模式那点事儿
观察者模式(Observer Pattern),又称为发布/订阅模式。
定义:对象间的一种一对多的依赖关系,当一个对象的状态发生改变的时候,所有依赖于他的对象都得到通知并被自动更新。
主要角色:观察者和被观察者。
实现:如果观察者和被观察者之间的的互动关系通过类的直接调用,就会增加观察者和被观察者之间的耦合性。在具体的实现中,我们需要面向接口编程,让被观察者管理观察者对象类型的接口,然后调用接口方法更新观察者。
类图:
实例描述:高温预警系统获取温度。如果温度高于35度,则计算温度所属的预警级别发出对应的预警信息,并通知订阅该预警信息的各个机构,如:学校,公园,个人 等。如果不高于35度的不发出预警信息。
代码:
//被观察者接口 package com.demo.Subject; import com.demo.Observer.IObserver; public interface ISubject { public boolean add(IObserver observer); public boolean remove(IObserver observer); public void notifyAllObserver(); public void setTemperature(float temperature); public String temperatureReport(); }
//被观察者实现 package com.demo.Subject; import java.util.Iterator; import java.util.Vector; import com.demo.Observer.IObserver; public class Subject implements ISubject{ private float temperature; private String waringlevel; private Vector<IObserver> vector; //初始化vector容器 public Subject(){ vector = new Vector<IObserver>(); } //增加观察者 @Override public boolean add(IObserver observer) { if(observer != null && !vector.contains(observer)){ return vector.add(observer); } return false; } //删除观察者 @Override public boolean remove(IObserver observer) { return vector.remove(observer); } //通知观察者 @Override public void notifyAllObserver() { System.out.println("气象部门发布高温"+this.waringlevel+"警报"); Iterator<IObserver> iterator = vector.iterator(); while(iterator.hasNext()){ (iterator.next()).update(this); } } //根据温度蛇之预警级别 @Override public void setTemperature(float temperature) { this.temperature = temperature; this.invoke(); } @Override public String temperatureReport() { return "温度"+this.temperature; } private void invoke(){ if(this.temperature >= 35){ if(this.temperature < 37){ this.waringlevel = "黄色"; } if(this.temperature < 40){ this.waringlevel = "橙色"; } if(this.temperature >= 40 ){ this.waringlevel = "红色"; } //通知所有观察者 this.notifyAllObserver(); } } }
//观察者接口 package com.demo.Observer; import com.demo.Subject.ISubject; //观察者接口响应被观察者的变化 public interface IObserver { public void update(ISubject subject); }
//个人观察者 package com.demo.Observer; import com.demo.Subject.ISubject; //个人观察者 public class Person implements IObserver { @Override public void update(ISubject subject) { System.out.println("个人收到高温预警:"+subject.temperatureReport()); } }
//公园 package com.demo.Observer; import com.demo.Subject.ISubject; public class Park implements IObserver{ public void update(ISubject subject) { System.out.println("公园收到高温预警:"+subject.temperatureReport()); } }
//学校 package com.demo.Observer; import com.demo.Subject.ISubject; public class School implements IObserver{ public void update(ISubject subject) { System.out.println("学校收到高温预警:"+subject.temperatureReport()); } }
//测试 package com.demo; import java.util.Random; import com.demo.Observer.Park; import com.demo.Observer.Person; import com.demo.Observer.School; import com.demo.Subject.ISubject; import com.demo.Subject.Subject; public class Client { public static void main (String [] args){ ISubject subject = new Subject(); subject.add(new Person()); subject.add(new School()); subject.add(new Park()); Random random = new Random(); for(int i = 0; i < 10; i++){ //设置随机温度 subject.setTemperature(random.nextInt(100)); } } }