标签:
观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。
-- 阎宏博士的《JAVA与模式》
一个普通的Button,当被按下时将自己的pressed状态改为true
1 public class MyButton { 2 private boolean pressedState = false; 3 4 public boolean isPressed() { 5 return pressedState; 6 } 7 8 public void pressed() { 9 pressedState = true; 10 } 11 }
要想在Button按下后处理自己的业务,则必须启动一个线程不断查看Button的状态
public class Business implements Runnable { private MyButton btn; public Business(MyButton btn) { this.btn = btn; } @Override public void run() { while(!btn.isPressed()) { try { TimeUnit.MILLISECONDS.sleep(200); } catch (InterruptedException e) { e.printStackTrace(); } } process(); } private void process() { System.out.println("Button pressed!"); } }
测试
1 public class Test { 2 public static void main(String[] args) throws InterruptedException { 3 MyButton btn = new MyButton(); 4 Business business = new Business(btn); 5 new Thread(business).start(); 6 TimeUnit.SECONDS.sleep(3); 7 btn.pressed(); 8 } 9 }
OK,虽然满足了需求,但很浪费资源,因为所有等待该Button按下时处理业务的对象必须启动一个线程实时看看Button的状态。
Button里增加对业务的引用,用于被按下时通知业务做出响应
public class MyButton { private boolean pressedState = false; private Business business; public MyButton(Business business) { this.business = business; } public boolean isPressed() { return pressedState; } public void pressed() { pressedState = true; business.process(); } }
此时,业务这块需提供对Button被按下时的响应
public class Business { public void process() { System.out.println("Button pressed!"); } }
测试
public class Test { public static void main(String[] args) throws InterruptedException { Business business = new Business(); MyButton btn = new MyButton(business); TimeUnit.SECONDS.sleep(3); btn.pressed(); } }
OK,这时效率问题已经不存在了,可是现实中,Business不可能都一样,且很多情况下需要根据Button按下的时间,事件源做出不同的响应。
封装一个事件源
public class ActionEvent { long when; Object source; public ActionEvent(long when, Object source) { super(); this.when = when; this.source = source; } public long getWhen() { return System.currentTimeMillis(); } public Object getSource() { return source; } }
抽象出需要对Button被按下时做出响应的业务接口
public interface ActionListener { public void actionPerformed(ActionEvent e); }
需要对Button被按下做出响应的业务
public class Business implements ActionListener { @Override public void actionPerformed(ActionEvent e) { System.out.println("Button pressed! --" + e.getWhen()); } }
重新封装Button
public class MyButton { private List<ActionListener> actionListeners = new ArrayList<ActionListener>(); private boolean pressedState = false; public void addActionListeners(ActionListener l) { actionListeners.add(l); } public boolean isPressed() { return pressedState; } public void pressed() { pressedState = true; ActionEvent e = new ActionEvent(System.currentTimeMillis(), this); for(int i=0; i<actionListeners.size(); i++) { ActionListener l = actionListeners.get(i); l.actionPerformed(e); } } }
测试
public class Test { public static void main(String[] args) throws InterruptedException { Business business = new Business(); MyButton btn = new MyButton(); btn.addActionListeners(business); TimeUnit.SECONDS.sleep(3); btn.pressed(); } }
OK,这就是JDK中事件的处理逻辑,也是观察者模式的完美应用。
标签:
原文地址:http://www.cnblogs.com/wangj1130/p/4822597.html