观察者模式

我觉得观察者在java中的应用还是挺多的,比如最近挺火的Android开源项目EventBus 就是应用观察者模式实现的,《Head First 设计模式》一书中将观察者模式放到了第一章。

观察者模式又叫做 发布/订阅模式 主要分为 观察者者(Observer) 和 主题 (Subject)也是被观察者.

当Subject中的数据发生变化时会通知这个Subject下面的所有订阅者。类似于我们显示中的电视,电视台是一个Subject也就是被观察者,通过电视观看节目的观众都是观察者(Observer),当电视台播放节目的时候,观众都可以收看的到。他们之间是一对多得关系,一个主题可以有多个观察者.

首先创建2个接口,分别是Subject (被观察者) ,Observer (观察者).

/**
 * 被观察者/主题
 */
public interface Subject {
	/**
	 * 注册观察者
	 */
	void registerObserver(Observer observer);
	/**
	 * 移除观察者
	 */
	void removeObserver(Observer observer);
	/**
	 * 通知所有观察者
	 */
	void notifyObserver();
	
}
/**
 * 观察者
 */
public interface Observer {
	/**
	 * 更新观察者的数据
	 */
	void update(String message);
}

其中被观察者有3个方法,观察者有1个方法。他们的作用看注释就可以理解。

下面看他们的具体实现类,首先是被观察者

/**
 * 电视台类
 */
public class TvStation implements Subject {
	
	List<Observer> observers;
	private String program = "";
	
	public TvStation() {
		observers = new ArrayList<Observer>();
	}
	/**
	 * 注册观察者
	 */
	@Override
	public void registerObserver(Observer observer) {
		observers.add(observer);
	}
	/**
	 * 移除观察者
	 */
	@Override
	public void removeObserver(Observer observer) {
		int index = observers.indexOf(observer);
		if(index >= 0)
			observers.remove(observer);
	}
	/**
	 * 通知观察者更新数据
	 */
	@Override
	public void notifyObserver() {
		for (Observer observer : observers) {
			observer.update(program);
		}
	}
	/**
	 * 修改节目
	 * @param programName
	 */
	public void changeProgram(String programName){
		this.program = programName;
		notifyObserver();
	}
}

然后是观察者

/**
 * 观众
 */
public class Viewers implements Observer {

	Subject subject;
	String message = "Hello";
	
	/**
	 * 实例化观察者的时候传入被观察者
	 * 方便 注册和注销
	 * @param subject
	 */
	public Viewers(Subject subject){
		this.subject = subject;
		subject.registerObserver(this);
	}
	/**
	 * 更新
	 */
	@Override
	public void update(String message) {
		this.message = message;
	}
	/**
	 * 展示数据
	 */
	public void display(){
		System.out.println(message);
	}
	/**
	 * 关闭电视,不再收看节目
	 */
	public void closeTv(){
		subject.removeObserver(this);
	}

}

当添加新的观察者的时候,只需要实现Observer接口,在实例化的时候在主题里注册一下,当不想再观看节目的时候,调用closeTv 方法,从电视台注销即可。

下面测试一下我们写的代码

public class Main {
	
	public static void main(String[] args) {
		//初始化被观察者 电视台为湖南卫视
		TvStation huNanTV = new TvStation();
		//初始化光中
		Viewers viewer = new Viewers(huNanTV);
		//观众正在收看的节目
		viewer.display();
		//电视台改了播放节目
		huNanTV.changeProgram("变形计");
		viewer.display();
	}
}

执行结果如下:

您正在收看 : 天天向上

您正在收看 : 变形计

你可能感兴趣的:(java,设计模式,观察者模式)