文章来源:软件秘笈--设计模式那点事儿观察者模式(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));
}
}
}