解决、解耦的钥匙——观察者模式

1.观察者模式的定义

定义了对象间的一对多依赖关系,当对象发生改变时,所有依赖于它的对象都将收到通知并自动更新。

2.观察者模式的使用场景

  • 关联行为场景,需要注意的是,关联行为是可以拆分的,而不是“组合”关系;
  • 事件多级触发场景;
  • 跨系统的消息交换场景,如消息队列、事件总线的处理机制。

3.观察者模式的UML类图

解决、解耦的钥匙——观察者模式_第1张图片

4.观察者模式的实现

/**
 * 观察者接口
 * @author Administrator
 *
 */
public interface Observer {
	void update(Observable o,Object arg);
}
/**
 * 被观察对象抽象类
 * @author Administrator
 *
 */
public abstract class Observable {
	//用一个List来保存该对象上所有绑定的时间监听器
	List observers = new ArrayList();
	
	//定义一个方法,用于从该主题上注册观察者
	public void registObserver(Observer o) {
		observers.add(o);
	}
	
	//定义一个方法,用于从该主题上删除观察者
	public void removeObserver(Observer o) {
		observers.remove(o);
	}
	
	//通知该主题上注册的所有观察者
	public void notifyObservers(Object value) {
		//遍历注册到该被观察者上的所有观察者
		for(Observer o:observers) {
			//显示调用每个观察者的update()方法
			o.update(this, value);
		}
	}
}
/**
 * 被观察者实现类
 * @author Administrator
 *
 */
public class Product extends Observable{
	//定义两个成员变量
	private String name;
	private double price;
	//无参数的构造器
	public Product() {}
	public Product(String name,double price) {
		this.name = name;
		this.price = price;
	}
	
	public String getName() {
		return name;
	}
	
	//当程序代用name的setter方法来修改Product的name成员变量时
	//程序自然触发该对象上注册的所有观察者
	public void setName(String name) {
		this.name=name;
		notifyObservers(name);
	}
	
	public double getPrice() {
		return price;
	}
	
	//当程序代用price的setter方法来修改Product的price成员变量时
	//程序自然触发该对象上注册的所有观察者
	public void setPrice(double price) {
		this.price = price;
		notifyObservers(price);
	}
}
/**
 * Price观察者
 * @author Administrator
 *
 */
public class PriceObserver implements Observer{

	//实现观察者必须实现的update方法
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		if(arg instanceof Double) {
			System.out.println("观察者名:"+o+"物品的价格已改变为:"+arg);
		}
	}

}
/**
 * Name观察者
 * @author Administrator
 *
 */
public class NameObserver implements Observer{
	//实现观察者必须实现的update方法
	@Override
	public void update(Observable o, Object arg) {
		// TODO Auto-generated method stub
		if(arg instanceof String) {
			//将产品名称改变值放在name中
			String name = (String) arg;
			//启动一个JFrame窗口来显示被观察对象的状态改变
			JFrame f = new JFrame("观察者");
			JLabel l = new JLabel("名称改变为"+name);
			f.add(l);
			f.pack();
			f.setVisible(true);
			System.out.println("名观察者:"+o+"物品名称已经改变为:"+name);
		}
	}

}
/**
 * 程序入口,测试观察者模式
 * @author Administrator
 *
 */
public class ObserverTest {
	public static void main(String[] args) {
		//创建产品
		Product p = new Product("AA",176);
		//创建两个观察者
		NameObserver no = new NameObserver();
		PriceObserver po = new PriceObserver();
		//注册观察者
		p.registObserver(no);
		p.registObserver(po);
		
		//利用setter方法改变Product的name和price属性
		p.setName("BB");
		p.setPrice(345f);
	}
}

5.总结

观察者模式主要的作用就是对象解耦,将观察者与被观察者完全隔离,只依赖于Observer和Observable抽象。

优点

  1. 观察者和被观察者之间是抽象耦合,应对业务变化;
  2. 增强系统灵活性、可扩展性。

缺点
在应用观察者模式时需要考虑一下开发效率和运行效率问题,程序中包括一个被观察者、多个观察者、开发和调试等内容会比较复杂,而且在Java中消息的通知默认是顺序执行,一个观察者卡顿,会影响整体的执行效率,在这种情况下,一般考虑采用异步的方式。

你可能感兴趣的:(设计模式,开发语言)