Java程序性能优化 读书笔记(六)设计模式:观察者模式

一、观察者模式

观察者模式定义了对象间的一种一对多依赖关系,使得每当一个对象改变状态,则所有依赖于它的对象都会得到通知并被自动更新它将观察者和被观察者的对象分离开。提高了应用程序的可维护性和重用性。观察者模式又称为发布/订阅(Publish/Subscribe)模式

观察者模式的应用场景

1、 对一个对象状态的更新,需要其他对象同步更新,而且其他对象的数量动态可变。

2、 对象仅需要将自己的更新通知给其他对象而不需要知道其他对象的细节。

观察者模式的优点

1、 Subject和Observer之间是松耦合的,分别可以各自独立改变。

2、 Subject在发送广播通知的时候,无须指定具体的Observer,Observer可以自己决定是否要订阅Subject的通知。

3、 遵守大部分GRASP原则和常用设计原则,高内聚、低偶合

观察者模式的缺陷

1、 松偶合导致代码关系不明显,有时可能难以理解。

2、 如果一个Subject被大量Observer订阅的话,在广播通知的时候可能会有效率问题

二、观察者模式的实现

实现观察者模式有很多形式,一种是“注册---通知---撤销注册”的形式。

1. 观察者Observer:所有潜在的观察者必须实现观察者接口,这个接口只有update方法,当主题改变时,它被调用。

public interface Observer
{
    public void update(float temprature);
}

2. 具体观察者ConcreteObserver: 具体观察者可以是任何实现了Observer接口的类。观察者必须注册具体主题,一边接收更新。

public class ConcreteObserver implements Observer
{
    private float temperature;
    private final Subject subject;

    public ConcreteObserver(final Subject subject)
    {
        this.subject = subject;
        this.subject.registerObserver(this);
    }

    public float getTemperature()
    {
        return temperature;
    }

    public void setTemperature(final float temperature)
    {
        this.temperature = temperature;
    }

    @Override
    public void update(final float temperature)
    {
        this.temperature = temperature;
    }
}

3. 可观察者Subject: 主题接口,即可观察者Observable,对象使用此接口注册为观察者,或者把自己从观察者中删除,每个主题可以有多个观察者。

public interface Subject
{
    public void registerObserver(Observer o);

    public void removeObserver(Observer o);

    public void notifyObservers();

}

4. 具体可观察者ConcreteSubject: 一个具体主题实现了主题接口,除了注册和撤销之外,具体主题还实现了notifyObservers()方法,这个方法用来在主题状态改变时更新所有观察者。具体主题也可能有设置和获取状态的方法。

public class ConcreteSubject implements Subject
{
    private final List<Observer> observers;
    private float temperature;

    public float getTemperature()
    {
        return temperature;
    }

    private void temperatureChanged()
    {
        this.notifyObservers();
    }

    public void setTemperature(final float temperature)
    {
        this.temperature = temperature;
        this.temperatureChanged();
    }

    public ConcreteSubject()
    {
        observers = new ArrayList<Observer>();
    }

    @Override
    public void registerObserver(final Observer o)
    {
        observers.add(o);
    }

    @Override
    public void removeObserver(final Observer o)
    {
        if (observers.indexOf(o) >= 0)
        {
            observers.remove(o);
        }
    }

    @Override
    public void notifyObservers()
    {
        for (final Observer o : observers)
        {
            o.update(temperature);
        }
    }
}

客户端使用代码如下:

public class Client
{
    public static void main(final String[] args)
    {
        final ConcreteSubject sb = new ConcreteSubject();
        sb.setTemperature((float) 20.00);

        final Observer o = new ConcreteObserver(sb);
        sb.setTemperature((float) 21.00);

    }
}

三、JDK Observable

在java.util包中包含有基本的Observer接口和Observable抽象类。功能上和Subject接口和Observer接口类似.不过在使用上,就方便多了,因为许多功能比如说注册,删除,通知观察者的那些功能已经内置好了。Swing编程中的JButton等常用控件均使用观察者模式实现。

Button的处理代码:

JButton btn = new JButton();  
        btn.addActionListener(new ActionListener() {  
              
            @Override  
            public void actionPerformed(ActionEvent e) {  
                // TODO Auto-generated method stub  
                //此处做事件处理  
            }  
        });
Button的添加代码:
public static void main(String[] args) {
	JFrame p = new JFrame();
	JButton btn = new JButton("Click Me");
	btn.addActionListener(new BtnListener());
	p.add(btn);
	p.pack();
	p.setVisible(true);	
} 

四、推和拉

“推”的方式是指,Subject维护一份观察者的列表,每当有更新发生,Subject会把更新消息主动推送到各个Observer去

“拉”的方式是指,各个Observer维护各自所关心的Subject列表,自行决定在合适的时间去Subject获取相应的更新数据。

 

推”的好处包括

1、高效。如果没有更新发生,不会有任何更新消息推送的动作,即每次消息推送都发生在确确实实的更新事件之后,都是有意义的。

2、实时。事件发生后的第一时间即可触发通知操作。

3、可以由Subject确立通知的时间,可以避开一些繁忙时间

4、可以表达出不同事件发生的先后顺序

 

“拉”的好处包括

1、如果观察者众多,Subject来维护订阅者的列表,可能困难,或者臃肿,把订阅关系解脱到Observer去完成。

2、Observer可以不理会它不关心的变更事件,只需要去获取自己感兴趣的事件即可。

3、Observer可以自行决定获取更新事件的时间

4、拉的形式可以让Subject更好地控制各个Observer每次查询更新的访问权限













评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值