1. 程式人生 > >Java設計模式六:觀察者模式(Observer)

Java設計模式六:觀察者模式(Observer)

觀察者模式定義了物件間的一種一對多依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。
它將觀察者和被觀察者的物件分離開。提高了應用程式的可維護性和重用性。
實現觀察者模式有很多形式,一種是“註冊---通知---撤銷註冊”的形式。
觀察者Observer:所有潛在的觀察者必須實現觀察者介面,這個介面只有update方法,當主題改變時,它被呼叫。
具體觀察者ConcreteObserver: 具體觀察者可以是任何實現了Observer介面的類。觀察者必須註冊具體主題,一邊接收更新。
可觀察者Subject: 主題介面,即可觀察者Observable,物件使用此介面註冊為觀察者,或者把自己從觀察者中刪除,每個主題可以有多個觀察者。
具體可觀察者ConcreteSubject: 一個具體主題實現了主題介面,除了註冊和撤銷之外,具體主題還實現了notifyObservers()方法,這個方法用來在主題狀態改變時更新所有觀察者。具體主題也可能有設定和獲取狀態的方法。

類圖:

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

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

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

    public void removeObserver(Observer o);

    public void 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);

    }
}