詳解Java編程的Observer觀察者設(shè)計模式
java語言里包含了許多對設(shè)計模式的直接支持,如command模式,agent模式,observer模式等。雖然java提供的對這些模式的支持很簡單,不能滿足比較復(fù)雜的應(yīng)用。但在簡單的場景下,使用這些類往往能夠得到立桿見影的效果。所以,如果沒有什么特殊需求,還是最好利用java的這些類。
Observer模式,又稱監(jiān)聽模式,觀察者模式,是經(jīng)典設(shè)計模式之一(one of GOF)。java語言中,對這種模式支持的類和接口主要有以下幾個,全部來自java.beans包:
java.beans.PropertyChangeListener (interface) java.beans.PropertyChangeSupport (class) java.beans.PropertyChangeEvent (class) java.beans.PropertyChangeListener
這是一個接口,很顯然,所有實現(xiàn)這個接口的類就是listener啦(或者叫observer),它會對被監(jiān)聽的對象的某些變化感興趣。這個接口就一個方法:
public void propertyChange(PropertyChangeEvent evt) { // TODO Auto-generated method stub }
接口定義很簡單,作用也很明顯。接受一個event(被監(jiān)聽者產(chǎn)生的PropertyChangeEvent),然后根據(jù)這個event做點反應(yīng)。
java.beans.PropertyChangeSupport
這個類用在被觀察者的類里,用來保存注冊的觀察者,并負(fù)責(zé)向他們提供被觀察者的變化信息。這個類的方法也不多,不過還是只介紹100%用到的,要不腦子就不夠使了,呵呵。
public PropertyChangeSupport(Object sourceBean)
這是構(gòu)造函數(shù),參數(shù)就是被監(jiān)聽者。PropertyChangeListener一般作為被監(jiān)聽者的一個屬性。一般如下使用:
private PropertyChangeSupport listeners = new PropertyChangeSupport(this);
注意,這個listeners可不是只代表一個監(jiān)聽者,他可能是一群監(jiān)聽者。那么如何這些listeners是誰呢?這回用到下面的方法了。
public void addPropertyChangeListener(PropertyChangeListener listener)
這個類太容易了,把監(jiān)聽者加進(jìn)來。就像開十七大一樣,記者想要采訪,就得先登記一下。顯然這個方法可以多次調(diào)用(add嘛)。有加就有減:
public void removePropertyChangeListener(PropertyChangeListener listener)
如果這個監(jiān)聽者對被監(jiān)聽者的任何變化多不感興趣了,就被被監(jiān)聽者趕了出去。
好了,記者都到齊了,被監(jiān)聽者有變化了就該通知人家了,使用如下方法的一個:
public void firePropertyChange(PropertyChangeEvent evt) public void firePropertyChange(String propertyName, boolean oldValue, boolean newValue) public void firePropertyChange(String propertyName, int oldValue, int newValue) public void firePropertyChange(String propertyName, Object oldValue, Object newValue)
實際上,后三個方法的參數(shù)都會封裝成PropertyChangeEvent,然后調(diào)用第一個方法。不過在實際中,我們還是喜歡直接調(diào)用后三個中的一個,封裝的事我們就不管了。后三個方法的參數(shù)都是三個,其中的oldValue和newValue就是改變前后的值,第一個就是給改變一個名字,好讓監(jiān)聽者們根據(jù)這個名子來做響應(yīng)。就像開會,政府的所有信息都會被記者聽到,但是有的記者只對臺灣問題感興趣,而有的記者對中日問題感興趣。
對PropertyChangeSupport方法的介紹就這么多吧。注意,PropertyChangeSupport既然被用到了被觀察者的類(一般是一個model)里,那么他的這些方法就只在被觀察這里調(diào)用。
java.beans.PropertyChangeEvent
這個類我也懶得介紹,看看他的主要方法就明白怎么回事了
public String getPropertyName() public Object getNewValue() public Object getOldValue()
就者三個類,再有就是具體問題具體分析了。來個例子吧,首先是被觀察者:
public class Domain{ protected String id; protected String name; protected String desName; protected PropertyChangeSupport listeners = new PropertyChangeSupport(this); public String getId() { return id; } public void setId(String id) { this.id = id; firePropertyChange("Domain.id", null, id); } public String getDesName() { return desName; } public void setDesName(String desName) { this.desName = desName; firePropertyChange("Domain.desName", null, desName); } public String getName() { return name; } public void setName(String name) { this.name = name; firePropertyChange("Domain.name", null, name); } public void addPropertyChangeListener(PropertyChangeListener listener) { listeners.addPropertyChangeListener(listener); } public void firePropertyChange(String propName, Object oldValue, Object newValue) { listeners.firePropertyChange(propName, oldValue, newValue); } public void removePropertyChangeListener(PropertyChangeListener listener) { listeners.removePropertyChangeListener(listener); } }
有人對Domain的三個屬性感興趣。下面就是這些人中的一個:
public class SimpleObserver implements PropertyChangeListener { .... @Override public void propertyChange(PropertyChangeEvent evt) { if(evt.getPropertyName().equals("Domain.name")){ //do some work } } }
下面是個簡單的測試類:
public class SimpleTest{ public static void main(String[] args) { SimpleObserver observer = new SimpleObserver(); Domain domain = new Domain(); domain.addPropertyChangeListener(observer); domain.setName("yangsq"); ...... } }
很顯然,可以觀察到SimpleObserver中propertyChange方法的執(zhí)行。
相關(guān)文章
SpringMVC實現(xiàn)自定義類型轉(zhuǎn)換器
本篇文章主要介紹了SpringMVC實現(xiàn)自定義類型轉(zhuǎn)換器 ,詳細(xì)的介紹了自定義類型轉(zhuǎn)換器的用法和好處,有興趣的可以了解一下。2017-04-04Java FileInputStream讀中文亂碼問題解決方案
這篇文章主要介紹了Java FileInputStream讀中文亂碼問題解決方案,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友可以參考下2020-10-10