Java設計模式六:觀察者模式(Observer)
阿新 • • 發佈:2019-02-01
觀察者模式定義了物件間的一種一對多依賴關係,使得每當一個物件改變狀態,則所有依賴於它的物件都會得到通知並被自動更新。
它將觀察者和被觀察者的物件分離開。提高了應用程式的可維護性和重用性。
實現觀察者模式有很多形式,一種是“註冊---通知---撤銷註冊”的形式。
觀察者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);
}
}
它將觀察者和被觀察者的物件分離開。提高了應用程式的可維護性和重用性。
實現觀察者模式有很多形式,一種是“註冊---通知---撤銷註冊”的形式。
觀察者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);
}
}