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();
}
}