Android使用的設計模式1——觀察者模式

  設計模式,對程序員來講是一個坎,想在程序員這條路走得更遠,設計模式是你的必修課。從大學時代接觸GoF到工做幾年後從新看設計模式,每次感受都不同。此次想借着分析Android Framework源碼的機會,順道整理一下設計模式的知識。html

  今天主要是先講一下觀察者模式,觀察者模式對於作系統或者作公共庫的朋友來講,應該很熟悉,基本上全部系統都會用到這個模式。整理的時候,主要是對模式進行進步講解而後結合Android裏面應用進行說明。設計模式的說明主要是參考《研磨設計模式》這本書,這本書講解了GoF裏面23種模式,並且比GoF更容易理解。若是對設計模式不瞭解的朋友,能夠看看《研磨設計模式》這本書。程序員

  結合Android源碼的時候,主要是針對應用層的代碼說明,並且儘可能使用簡單例子代碼,因此不會出現太多Android系統級的代碼,大部分是咱們作APP開發時會編寫的代碼。設計模式

  這篇文章不會詳細介紹設計模式,只是整理設計模式核心概念,結合Android應用說明。ide

  (PS:新建的QQ羣,有興趣能夠加入一塊兒討論:Android羣:322599434)函數

 

一、觀察者模式spa

  觀察者模式:定義對象間的一種一對多的依賴關係,當一個對象的狀態發生改變時,全部依賴於它的對象都獲得通知並被自動更新。這種模式最經常使用在咱們熟悉的事件驅動模型裏面,像VC、Android界面裏面的事件響應,就是基於觀察者模式來實現。設計

  下面咱們看看觀察者模式的類圖關係(圖片是截取《研磨設計模式》裏面插圖):code

 

 

 

  • Subject是咱們定義目標對象,或者說被觀察對象。
  • ConcreteSubject是實際的被觀察對象。 
  • Observer是觀察者的接口,定義了回調接口。
  • ConcreteObserver是實際的觀察者對象。

 

二、觀察者模式含義server

  下面講解一下我的對觀察者模式的理解,其實這個模式在咱們平時工做中是很經常使用的模式,可能你已經使用過,缺沒有意識到。htm

  觀察者模式主要是針對一對多的數據更新。簡單來講就是,系統裏面某個元素更新了數據,而後有好幾個元素是使用了這個元素的數據。此時更新了數據的對象,就要通知其餘使用了它數據的對象,讓他們都進行更新。

  標準的觀察者對象是一對多的關係,不過咱們都知道設計模式裏面是很靈活,在咱們使用的時候,常常須要進行變形。對現有的標準模式進行適當的修改來適應設計需求。

  在咱們實際應用中,還會遇到一對1、或者多對一的狀況。一對一就是,一個目標對應一個觀察者。多對一是指多個目標對應一個觀察者。

 

三、觀察者模式的簡單實現

  下面給出一個最簡單的觀察者模式實現代碼,把代碼看懂了,再回頭看文字講解,會比較容易理解。下面是目標對象的接口和實現代碼,只作了一個最簡單的接口。

//Edited by mythou
//http://www.cnblogs.com/mythou/
   //目標對象接口
    public interface Subject
    {
        //調用這個方法註冊一個新的觀察者對象
        public void attach(Observer observer);
        
        //調用這個方法刪除一個已註冊的觀察者對象
        public void detach(Observer observer);
        
        //調用這個方法通知全部註冊的觀察者對象
        void notifyObservers();
    }  
    
    //目標對象實現
    public class ConcreteSubject implements Subject
    {
    //向量容器,保存全部註冊的觀察者
private Vector observersVector = new Vector(); public void attach(Observer observer) { observersVector.addElement(observer); } public void detach(Observer observer) { observersVector.removeElement(observer); } public void notifyObservers() { Enumeration enumeration = observers(); while(enumeration.hasMoreElements()) { ((Observer)enumeration.nextElement()).update(); } } }

 

下面是觀察者的實現:

//Edited by mythou
//http://www.cnblogs.com/mythou/
   //觀察者接口
    public interface Observer
    {
        void update();
    }
    
    //觀察者實現
    public class ConcreteObserver implements Observer
    {
        public void update()
        {
            System.out.println("The subject has changed! mythou notify");
        }
    }

 

應用中使用的代碼:

 //Edited by mythou
//http://www.cnblogs.com/mythou/
  //客戶端
    public class Client
    {
        private static ConcreteSubject subject;
        private static Observer observer;
        
        public static void main(String args[])
        {
            //建立目標對象
            subject = new ConcreteSubject();
            //建立觀察者對象
            observer = new ConcreteObserver();
            subject.attach(observer);
            subject.change("mythou has changed data!");
        }
    }

 

四、Android 應用開發中的觀察者模式

  在咱們作Android應用的時候,會大量使用觀察者模式,由於Framework層裏面的事件驅動都是基於觀察者模式實現的。另外在Framework層裏面的各類服務在數據變動的時候,也是經過觀察者模式實現上層數據更新。下面會講兩個例子來講明:

 A)控件中Listener監聽方式

  Android裏面最典型的觀察者就是咱們使用的各類控件監聽者。例以下面對某個按鈕的監聽:

 

//Edited by mythou
//http://www.cnblogs.com/mythou/
Button baiduclickButton = (Button)findViewById(R.id.button1);
//註冊觀察者 baiduclickButton.setOnClickListener(
new OnClickListener() {
  //觀察者實現 @Override
public void onClick(View arg0) { Log.d("Mythou_Log", "Click the button "); } });

 

  例如上面的代碼,註冊了一個按鈕的監聽方法。這裏其實是應用了一對一的觀察者模式,setOnClickListener()方法就是註冊一個觀察者,Button對象就是咱們要觀察的目標對象。而new出來的OnClickListener(),就是咱們實際的觀察者。

  每當咱們的目標按鈕對象被點擊,狀態發生變化的時候,就會經過回調註冊的OnClickListener觀察者的onClick方法會來通知觀察者,Button狀態發生變化。這裏的onClick至關於前面例子裏面的update方法。下面是Android源碼裏面對OnClickListener的定義,跟咱們前面定義一個觀察者接口相似。

//Edited by mythou
//http://www.cnblogs.com/mythou/
  public interface OnClickListener { /** * Called when a view has been clicked. * * @param v The view that was clicked. */
        void onClick(View v); }

 

B)GPS位置信息監聽

  上面對按鈕監聽是屬於一對一的觀察者模式,固然你也能夠用一個Listener監聽多個按鈕。下面咱們再講一個標準的一對多的觀察者模式的應用。在咱們使用GPS模塊的時候,須要監聽GPS模塊位置變化,一般咱們會編寫下面代碼:

 

 
 
//Edited by mythou
//http://www.cnblogs.com/mythou/
// 經過GPS定位
String LocateType= locationManager.GPS_PROVIDER;
Location location = locationManager.getLastKnownLocation(LocateType);
// 設置監聽器,設置自動更新間隔這裏設置1000ms,移動距離:0米。
locationManager.requestLocationUpdates(provider, 1000, 0, locationListener);
// 設置狀態監聽回調函數。statusListener是監聽的回調函數。
locationManager.addGpsStatusListener(statusListener); 

//監聽器實現
private final GpsStatus.Listener statusListener = new GpsStatus.Listener() 
{
    public void onGpsStatusChanged(int event) 
  {
      // GPS狀態變化時的回調,獲取當前狀態
      GpsStatus status = locationManager.getGpsStatus(null);
    //本身編寫的方法,獲取衛星狀態相關數據
       GetGPSStatus(event, status);
    }
};

 

  GPS位置服務是Framework的一個系統層服務,整個系統只有一個運行的實例。但實際使用時,可能會出現好幾個應用都在使用這個服務,所以會造成了一個一對多的觀察者例子。這裏不對代碼進行深刻對比講解,只要對照上面的講解,你就能夠把目標對象、觀察者接口、觀察者實現、數據更新回調接口找出來。有興趣的朋友還能夠追查Android的源碼,看看GpsStatus裏面的具體實現。

 

五、結語

  除了上面說的按鈕響應、GPS服務外,還有一個例子比較經典,就是咱們的BroadcastReceiver響應,也是基於觀察者模式來實現,下面總結裏面也會說到,觀察者模式支持廣播通訊。有關BroadcastReceiver是怎麼實現觀察者模式的,有興趣的朋友能夠本身對比代碼,和查看Android實現源碼,本身動手才能加深印象。引入設計模式是爲了對系統有更深刻的理解。下面總結一下觀察者模式的優缺點,方便咱們在使用的時候,能夠根據實際狀況衡量。

A)優勢

  • 實現觀察者和目標對象之間的抽象耦合。
  • 觀察者模式支持廣播通訊。被觀察者會全部的登記過的觀察者發出通知。

B)缺點

  • 可能會引發多餘的數據通知。
  • 可能會致使通知數據循環,致使死鎖產生。

 

 

 

Edited by mythou

原創博文,轉載請標明出處:http://www.cnblogs.com/mythou/p/3370340.html 

相關文章
相關標籤/搜索