简单_从java ui事件模型看发布订阅模式和观察者模式的区别

jdk中的UI事件模型使用的是发布订阅模式,但是jdk也提供了观察者模式的支持,对于名字上的区别可能发现不了什么东东,为什么UI事件模型用的是发布订阅模式而非观察者模式,在参考了一些网上的文章后明白了一点,现记录下。

先来看看jdk中ui事件模型的理论代码(参考jdk写的):
package design.eventListener2;
/** 
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-4 上午10:51:36 <br>
 * 
 */
public class Test {
	public static void main(String[] args) {
		AbstractButton btn = new AbstractButton();
		//添加事件
		btn.addActionListener(new ActionListener() {
			
			public void actionPerformed(ActionEvent e) {
				System.out.println("button event");
				System.out.println("事件源:"+e.getSource());
			}
		});
		//手动触发事件
		btn.fireActionListener(null);
		
		/*
		 * 订阅发布模式
		 * jdk中的UI事件模型其实就是订阅发布模式,与订阅发布模式相似的还有一个模式是
		 * 观察者模式,为什么不用观察者模式我想可能是基于2个方面的考虑:
		 * 1、观察者模式是基于观察者和被观察者2个对象来考虑的,而UI控件兼具观察者和被观察者两种角色
		 * 2、JDK提供的Observer这个现成的观察者模式的update方法把名字限定死了,
		 * UI事件各有各的名字限定死肯定是不合理的
		 */
	}
}

package design.eventListener2;

/**
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-4 上午10:34:38 <br>
 * 
 */
public class AbstractButton {
	EventListenerList listener = new EventListenerList();

	//订阅
	public void addActionListener(ActionListener e) {
		listener.addActionListener(e);
	}

	//发布
	public void fireActionListener(ActionEvent e) {
		for (int i = 0; i < listener.getListener().size(); i++) {
			ActionEvent source = new ActionEvent(AbstractButton.this);
			listener.getListener().get(i).actionPerformed(source);
		}
	}

//	class Handler implements ActionListener {
//
//		public void actionPerformed(ActionEvent e) {
//			fireActionListener(e);
//		}
//	}
}

package design.eventListener2;

import java.util.EventListener;

/**
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-4 上午10:35:55 <br>
 * 
 */
public interface ActionListener extends EventListener {
	void actionPerformed(ActionEvent e);
}

package design.eventListener2;

import java.util.Vector;

/**
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-4 上午10:38:34 <br>
 * 
 */
public class EventListenerList {
	private Vector<ActionListener> listener = new Vector<ActionListener>();

	public Vector<ActionListener> getListener() {
		return listener;
	}

	public void addActionListener(ActionListener e) {
		listener.add(e);
	}
}

package design.eventListener2;

import java.util.EventObject;

/**
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-4 上午10:36:58 <br>
 * 
 */
public class ActionEvent extends EventObject {

	public ActionEvent(Object source) {
		super(source);
		// System.out.println(source + "触发了");
	}
}


毫无疑问这样的设计是good的,但是用观察者模式来对ui事件模型进行设计会是个什么样子的呢?
package design.uiObserver;

import java.util.Observable;

/** 
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-28 下午10:32:25 <br>
 * 
 */
public class Test {
	public static void main(String[] args) {
		AbstractButton btn = new AbstractButton();
		btn.addObserver(btn);//注册click事件
		//模拟触发事件
		btn.setChanged();//被观察者已经改变
		btn.notifyObservers();//通知观察者被观察者已经改变
		/*
		 * 观察者模式去实现UI的事件模型,由于UI控件模型具有双重的性质,
		 * 即是观察者也是被观察者,而JDK的观察者模式中,观察者必须实现Observer接口,
		 * 被观察者必须继承Observable类,但是UI控件不能这样来设计
		 * AbstractButton extends Observable implements java.util.Observer
		 */
	}
}

package design.uiObserver;

import java.util.Observable;

/** 
 * @author 作者 E-mail: [email protected]
 * @version 创建时间:2012-1-28 下午10:31:24 <br>
 * 
 */
public class AbstractButton extends Observable implements java.util.Observer{

	public void update(Observable o, Object arg) {
		System.out.println("update:"+o);
	}
	@Override
	protected synchronized void setChanged() {
		super.setChanged();
	}
}

猜你喜欢

转载自jqsl2012.iteye.com/blog/1378745