设计模式系列之----观察者模式

观察者模式是一个广播机制的基础,实现1对N的联动,当1发生变化,N跟着相应变化,由此衍生了发布订阅模式,其方式分两种,①强制推送:当1发生变化,强制N也跟着发生变化,②拉的方式,即N方可以自己决定是否接收,只有当N这方有需要时才去获取最新的,不然就算1方变化,N这方也不更新。

 观察者接口和具体实现类:

/**
 *观察者接口
 */
public interface Observer {

	void update(Subject subject);//观察者接收一个推送过来的主题
	
}

//============================

/**
 *观察者具体实现类
 */
public class ObserverImpl implements Observer {

	private int state; //拥有与主体一致的状态,用于接收订阅的主题内容 
	
	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	@Override
	public void update(Subject subject) {
		this.state=((ConcreteSubject)subject).getState();//在具体观察者中进行同步状态更新
	}

}

主题基类和主题具体类

/**
 * 主体的基类,定义了一些公用方法,没有具体主题,也可以定义成抽象类
 */
public class Subject {

	public List<Observer> list=new ArrayList<Observer>();//在主体方定义一个容器存放注册的观察者
	
	public void registerObserver(Observer obs){
		list.add(obs);//注册观察者,即把需要订阅的观察者加进容器中
	}
	
	public void removeObserver(Observer obs){
		list.remove(obs);//移除观察者
	}
	
	//主题发生变化时,通知所有观察者进行更新
	public void notifyAllObservers(List<Observer> list){
		for (Observer observer : list) {
			observer.update(this);
		}
	}
	
}

//=================================================

/**
 *有具体主题的子类
 */
public class ConcreteSubject extends Subject {

	private int state;//模拟一个具体主题

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
		this.notifyAllObservers(list);//此步为关键,当主题发生变化时,主题中注册的观察者的状态也跟着进行更新
	}	
	
}

客户端调用:

		public static void main(String[] args) {
			
			ConcreteSubject concreteSubject = new ConcreteSubject();//目标主题,发布者
			
			ObserverImpl observer1=new ObserverImpl();
			ObserverImpl observer2=new ObserverImpl();
			ObserverImpl observer3=new ObserverImpl();
			
			concreteSubject.registerObserver(observer1);//注册观察者
			concreteSubject.registerObserver(observer2);
			concreteSubject.registerObserver(observer3); 
			
			concreteSubject.setState(1000);//目标主题状态为1000
			System.out.println(observer1.getState());
			System.out.println(observer2.getState());
			System.out.println(observer3.getState());//观察者的值也都为1000
			
			concreteSubject.setState(2000);//目标主题状态值发生改变
			System.out.println(observer1.getState());
			System.out.println(observer2.getState());
			System.out.println(observer3.getState());//观察者的值也改为2000
			
		}

以上代码是自己实现的观察者模式,实际上JavaSE中已经为我们提供了实现观察者模式的基础,java.util.Observable类和java.util.Observer接口,通过这两个对象可以方便的实现观察者模式,java.util.Observable相当于上面定义的Subject,Observable中定义好了一些常用的方法来添加观察者,移除观察者等,观察者只要实现Observer接口就具有观察者身份,可以被添加进来。  

/**
 * 继承JDK的Observable类实现主题
 */
public class ConcreteSubject extends Observable{

	private int state;

	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
		super.setChanged();//当次属性发生改变时,调用基类的setChanged()方法表示当前观察者有改变,
		                   //主要改变super.hasChanged()方法返回值,观察者可以通过此值判断目标对象是否已改变
		super.notifyObservers(this.state);//把当前发生改变的对象通知各个观察者
	} 
}

//===================================================

/**
 *实现JDK的观察者接口,实现更新方法
 */
public class ObserverImpl implements Observer {

	private int state;	
	
	public int getState() {
		return state;
	}

	public void setState(int state) {
		this.state = state;
	}

	@Override
	public void update(Observable o, Object obj) {
		setState(((ConcreteSubject)o).getState());
		//this.state =Integer.parseInt((String)obj);//也可以直接通过传递过来的参数赋值
	}
}

//==================================================

	public static void main(String[] args) {

		ConcreteSubject subject=new ConcreteSubject();
		
		ObserverImpl observer1=new ObserverImpl();
		ObserverImpl observer2=new ObserverImpl();
		ObserverImpl observer3=new ObserverImpl();
		
		subject.addObserver(observer1);
		subject.addObserver(observer2);
		subject.addObserver(observer3);
		
		subject.setState(10);
		
		System.out.println(observer1.getState());
		System.out.println(observer2.getState());
		System.out.println(observer3.getState());//观察者的值也都为1000
		
		subject.setState(2000);//目标主题状态值发生改变
		System.out.println(observer1.getState());
		System.out.println(observer2.getState());
		System.out.println(observer3.getState());//观察者的值也改为2000
		
	}

JavaEE中监听器就使用的是观察者模式

  

posted @ 2017-08-28 13:12  关键步就几步  阅读(183)  评论(0编辑  收藏  举报