设计模式--------观察者模式

介绍观察者模式的四大问题

  • 现在的写法有什么问题吗?
  • 为什么要用观察者模式?
  • 什么是观察者模式?
  • 观察者模式有什么好处?

采用一个案例来说明问题

  • 假如现有一个检测系统,其可以检测温度,湿度等,每当检测系统更改的时候,就需要发送更改的消息到温度显示器和湿度显示器上,以便实时观测变化

目前实现思路

  • 首先创建一个MonitorDate类,此类其中有DateChanged() 方法,将会在数据变化的时候自动调用(无需管怎么实现的)

  • 接着创建一个update接口,创建温度类,和湿度类,分别实现此接口

  • 最后在DateChanged方法中调用温度类和湿度类的update方法,以通知它们

  • 监测数据类

public class MonitorDate {
	
	private float temp;
	private float humidity;
	private TempDisplay tempDisplay;
	private HumidityDisplay humidityDisplay;
	
	public MonitorDate(TempDisplay tempDisplay, HumidityDisplay humidityDisplay) {
		this.tempDisplay = tempDisplay;
		this.humidityDisplay = humidityDisplay;
	}
	
	private void DateChanged() {
		tempDisplay.update(temp, humidity);
		humidityDisplay.update(temp, humidity);
	}
	
	public void setDate(float temp, float humidity) {
		this.temp = temp;
		this.humidity = humidity;
		DateChanged();
	}

}
  • 更新接口
public interface Observer {

	public void update(float temp, float humidity);
}

  • 温度显示类
public class TempDisplay implements Observer {

	@Override
	public void update(float temp, float humidity) {
		System.out.println("The temp is " + temp);
		
	}
	
}
  • 湿度显示类
public class HumidityDisplay implements Observer {

	@Override
	public void update(float temp, float humidity) {
		System.out.println("The humidity is " + humidity);
		
	}
}

  • Main
public class Main {
	
	public static void main(String[] args) {
		TempDisplay tempDisplay = new TempDisplay();
		HumidityDisplay humidityDisplay = new HumidityDisplay();
		
		MonitorDate monitorDate = new MonitorDate(tempDisplay, humidityDisplay);
		monitorDate.setDate(1.1f, 2.2f);
	}
}

// out
The temp is 1.1
The humidity is 2.2

这样实现有什么问题吗?

  • 对于每新增一个监测参数,都需要改代码
  • 无法动态的增加减少监测显示
  • 违反了设计原则之针对接口编程,而不是实现编程

什么是观察者模式

  • 在对象之间定义一对多的依赖,当一个对象改变状态,依赖它的对象都会收到通知,并自动更新

接下来使用观察者模式对此进行改造

  • 更新接口
public interface Observer {

	public void update(float temp, float humidity);
}

  • 湿度类
public class HumidityDisplay implements Observer {

	private MonitorDate monitorDate;
	
	public HumidityDisplay(MonitorDate monitorDate) {
		this.monitorDate = monitorDate;
		this.monitorDate.addObserver(this);
	}
	
	
	@Override
	public void update(float temp, float humidity) {
		System.out.println("The humidity is " + humidity);
		
	}
	
}
  • 温度类
public class TempDisplay implements Observer {

	private MonitorDate monitorDate;
	
	public TempDisplay(MonitorDate monitorDate) {
		this.monitorDate = monitorDate;
		this.monitorDate.addObserver(this);
	}
	
	
	@Override
	public void update(float temp, float humidity) {
		System.out.println("The temp is " + temp);
		
	}
	
}

  • 监测类
public class MonitorDate {

	private ArrayList<Observer> observers;
	private float temp;
	private float humidity;
	
	public MonitorDate() {
		observers = new ArrayList<Observer>();
	}
	
	public void addObserver(Observer o) {
		observers.add(o);
	}
	
	public void removeObserver(Observer o) {
		observers.remove(o);
	}
	
	
	public void notifyObserver() {
		for (int i = 0; i < observers.size(); i++) {
			observers.get(i).update(temp, humidity);
		}
	}
	
	public void setDate(float temp, float humidity) {
		this.temp = temp;
		this.humidity = humidity;
		notifyObserver();
	}

}
  • Main
public class Main {
	
	public static void main(String[] args) {
		MonitorDate monitorDate = new MonitorDate();
		TempDisplay tempDisplay = new TempDisplay(monitorDate);
		HumidityDisplay humidityDisplay = new HumidityDisplay(monitorDate);
		
		
		monitorDate.setDate(1.1f, 2.2f);
		
		
	}
}
// out
The temp is 1.1
The humidity is 2.2

观察者模式的好处

  • 松耦合
  • 可在运行时增加减少通知对象

使用java自带的观察者模式

  • Observable: 等于主题 (类)

    • 封装的方法
      • addObserver:添加观察者
      • deleteObserver:删除观察者
      • notifyObservers:通知观察者
      • notifyObservers(Object arg) :通知观察者,并传递参数
      • setChanged:设置数据已改变(需要设置true,才会使notifyObservers生效)
  • Observer:等于观察者 (接口)

    • update
  • 需要注意的是,使用java自带的Observable进行通知会导致通知的顺序不一定

  • 另外Observable是一个类,而且没有实现任何接口,这就导致了它是不能被复用的,而且其重要方法setChanged方法是protected的,这也导致了其不能被组合的方式使用,因为其实例化对象不能调用setChanged方法

  • 所以自带的还是有很多的问题,如果有必要最好使用自己创建的

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值