码迷,mamicode.com
首页 > 其他好文 > 详细

设计模式之观察者模式

时间:2015-09-20 00:22:36      阅读:237      评论:0      收藏:0      [点我收藏+]

标签:

设计模式 之 观察者模式

观察者模式是对象的行为模式,又叫发布-订阅(Publish/Subscribe)模式、模型-视图(Model/View)模式、源-监听器(Source/Listener)模式或从属者(Dependents)模式。

-- 阎宏博士的《JAVA与模式》


 

例:Button事件模型

 

第一版:以最简单的方式实现Button被按下时处理自己的业务

一个普通的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 }
View Code
要想在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!");
    }
}
View Code
测试
技术分享
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 }
View Code

 OK,虽然满足了需求,但很浪费资源,因为所有等待该Button按下时处理业务的对象必须启动一个线程实时看看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();
    }
}
View Code
此时,业务这块需提供对Button被按下时的响应
技术分享
public class Business {
    public void process() {
        System.out.println("Button pressed!");
    }
}
View Code
测试
技术分享
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();
    }
}
View Code

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;
    }
}
View Code
抽象出需要对Button被按下时做出响应的业务接口
技术分享
public interface ActionListener {
    public void actionPerformed(ActionEvent e);
}
View Code
需要对Button被按下做出响应的业务
技术分享
public class Business implements ActionListener {
    @Override
    public void actionPerformed(ActionEvent e) {
        System.out.println("Button pressed! --" + e.getWhen());
    }
}
View Code
重新封装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);
        }
    }
}
View Code
测试
技术分享
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();
    }
}
View Code

 OK,这就是JDK中事件的处理逻辑,也是观察者模式的完美应用。

 

设计模式之观察者模式

标签:

原文地址:http://www.cnblogs.com/wangj1130/p/4822597.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!