观察者模式

      观察者模式又叫做发布-订阅(Publish/Subscribe)模式,在设计模式这本书中是这样定义的:

      观察者模式定义了一种一对多的依赖关系,让多个观察者对象同时监听某一个主题对象。这个主题对象在状态发生变化时,会通知所有观察者对象,使它们能够自动更新自己。(DP)

      下面让我们来看一下观察者模式的结构图:



      主题(Subject)类:该抽象类把所有的观察者对象的引用保存在一个列表里;每个主题都可以有任何数量的观察者。主题提供一个接口可以加上或撤销观察者对象;

     具体主题实现类(ConcreteSubject):将有关状态存入具体观察着对象;在具体主题的内部状态改变时,给所有登记过的观察者发出通知;

     抽象观察者(Observer)类:为所有的具体观察者定义一个接口,在得到通知时更新自己; 

     具体观察者(ConcreteObserver):实现抽象观察者角色所要求的更新接口,以便使本身的状态与主题的状态相协调



    而Java的java.util包里面提供了一个Observable类以及一个Observer接口,构成Java语言对观察者模式的支持。

    Observable类:

     被观察者继承父类Observable实现被观察者,下面讲解一下里面的几个方法:

     1、addObserver(Observer o) 如果观察者与集合中已有的观察者不同,则向对象的观察者集中添加此观察者,参数则为要添加的观察者

     2、deleteObserver(Observer o)从对象的观察者集合中删除某个观察者

    3、setChanged()标记此 Observable 对象为已改变的对象,当调用该方法以后,hasChanged该方法的结果将返回true,调用下面的notifyObservers方法以后,则hasChanged将返回false

    4、notifyObservers()和notifyObservers(Object arg )如果 hasChanged 方法指示对象已改变,则通知其所有观察者,并调用 clearChanged 方法来指示此对象不再改变。

       该方法中的参数arg为Observer类中update方法中需要的参数,每个观察者都有其 update 方法,其调用参数有两个:observable 对象和 arg 参数。 



  下面写了一个该设计模式的小例子:

  一个加热器还有一个显示器,当加热器的温度改变了以后,会发出通知显示器,使其更新,而显示器有一个update的方法,显示改变以后的当前温度。

  

import java.util.Observable;

public class Heater extends Observable {
	private int temperature;

	public int getTemperature() {
		return temperature;
	}

	public void setTemperature(int temperature) {
		this.temperature = temperature;
	}

	public void boilWater() {
		for (int i = 90; i < 110; i++) {
			temperature = i;
			setChanged();
			notifyObservers("这是参数");
		}

	}
}


import java.util.Observable;
import java.util.Observer;

public class Display implements Observer {
	private String status;

	public Display() {
		status = "加热中";
	}

	public String getStatus() {
		return status;
	}

	public void setStatus(String status) {
		this.status = status;
	}

	@Override
	public void update(Observable arg0, Object arg1) {
		displayTemperature(((Heater) arg0).getTemperature());
		System.out.println(arg1.toString());
	}

	private void displayTemperature(int temperature) {
		if (temperature > 100) {
			this.setStatus("沸腾");
		}
		System.out.println("状态: " + status + "  现在温度: " 

+ temperature);
	}
}

public class OberverDesign {
	 public static void main(String[] args) {
	       Heater heater = new Heater();
	       Display display = new Display();
	       heater.addObserver(display);
	       heater.boilWater();
	    }
}

执行结果如下:

状态: 加热中  现在温度: 90
这是参数
状态: 加热中  现在温度: 91
这是参数
状态: 加热中  现在温度: 92
这是参数
状态: 加热中  现在温度: 93
这是参数
状态: 加热中  现在温度: 94
这是参数
状态: 加热中  现在温度: 95
这是参数
状态: 加热中  现在温度: 96
这是参数
状态: 加热中  现在温度: 97
这是参数
状态: 加热中  现在温度: 98
这是参数
状态: 加热中  现在温度: 99
这是参数
状态: 加热中  现在温度: 100
这是参数
状态: 沸腾  现在温度: 101
这是参数
状态: 沸腾  现在温度: 102
这是参数
状态: 沸腾  现在温度: 103
这是参数
状态: 沸腾  现在温度: 104
这是参数
状态: 沸腾  现在温度: 105
这是参数
状态: 沸腾  现在温度: 106
这是参数
状态: 沸腾  现在温度: 107
这是参数
状态: 沸腾  现在温度: 108
这是参数
状态: 沸腾  现在温度: 109
这是参数


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值