【UML】如何看Android的UML圖

    UML圖有不少類型,這裏只討論最重要也最經常使用的兩種 - 類圖和時序圖。

1. 類圖

    經過類圖,咱們能夠很容易的瞭解代碼架構,理清模塊之間的關係,html

    包括繼承(Inheritance),實現(realization),依賴(dependency),組合(Composition), 聚合(Aggregation), 關聯 (Association) 等等。編程

    下面就圖中給出的7種關係一一解讀。設計模式

    

1.1 Composition

    Compostion 是一種 Association 關係,但它更強調兩個類之間總體和局部關係,它暗示兩個類之間有着相同的生命週期,數據結構

    好比說圖中的三個1.多線程

  •   W 是 ViewRootImpl的成員變量之一,ViewRootImpl 對象的構造函數裏也構造了W,所以,當ViewRootImpl 析構時,W也被析構,他們的生命週期是一致的。
    public final class ViewRootImpl implements ViewParent,
            View.AttachInfo.Callbacks, HardwareRenderer.HardwareDrawCallbacks {
      ...
      final W mWindow;
      ...
      
      mWindow = new W(this); //互相引用,因此當一個銷燬時,另一個也沒法存在。
    
    View Code
  • 一樣相似的關係存在於 WindowManagerService 和 WindwoState 之間。

1.2  Realization

       Realization就是實現,在Java中體現爲implements 一個接口類interface, 在標準的C++中沒有明確的接口概念,但抽象類實際上起着和接口相似的功能,由於C++的Realization能夠體現爲繼承一個抽象類。在Android 的C++代碼中,有一個特殊的抽象類IInterface, 定義了PC接口類的一些基本方法。架構

1.3  Association

      有接口就會有引用,在UML中一根最普通的單向箭頭便是引用(關聯)關係。它的含義是,某個對象用到了一個其餘對象的接口或屬性。一般,Assocation 經過兩種方式獲取app

  •  依賴注入,經過構造函數或SetXXX()接口,好比說 WindowState 經過構造時傳入的參數獲取了對IWindow對象的引用
    WindowState(WindowManagerService service, Session s, IWindow c, WindowToken token,
               WindowState attachedWindow, int appOp, int seq, WindowManager.LayoutParams a,
               int viewVisibility, final DisplayContent displayContent)
    View Code
  • 間接獲取,經過調用其餘對象方法返回。
    mActivityManager = ActivityManagerNative.getDefault();
    View Code  

1.4 Android 的 IPC interface.

    C++和Java 的接口都只支持進程內的調用。爲了支持專門用於跨進程的接口調用,Android 專門作了一些規定。異步

    凡是以IXXXX 定義的接口類都可以支持IPC(固然,進程內也能夠調用IXXXX定義的接口)。ide

    當咱們在圖中看到一個IXXX 接口類,咱們即可以認爲這是一個進程的邊界,他的實現端和調用端對象運行在不一樣的進程裏(至少是不一樣的線程)。函數

    如上圖中,IWindow的兩端W對象 和 WindowState 對象就用不一樣的顏色來標明它們分屬於不一樣的進程,W運行在應用程序的進程裏,而WinState存在與System Server 進程裏。

1.5 Aggregation

    聚合表達了兩個類的從屬關係,但和Composition不一樣,他們的生命週期並不同。

    一個經典的例子就是工廠和車子,車子是工廠造出來的,工廠倒閉了,車子能夠繼續開,反之亦然。

    圖中PolicyManager 和 PhoneWindow就是相似的關係。

1.6 Inherritance

    就是最多見的繼承關係了。

    複雜的繼承關係很難閱讀和記憶,經過UML圖則方便不少,你能夠清楚到看出繼承關係,同時可以理解繼承的設計思想。

    好比說圖中右上角,PhoneWindow 繼承了Window 類,Activity 引用的是其基類Window的對象,但背後真正幹事的是PhoneWindow對象, 由於Acitivy 用的Window類對象是PolicyManager構造出來的。經過這種方式,PhoneWindow的實現細節被PolicyManager 和 Window 基類隱藏起來,從而大大下降了應用程序(Activity) 改變的概率。

    這個正是設計模式裏有名的工廠模式之一。

1.7  依賴

    依賴不一樣於引用,依賴者和被依賴着之間沒有直接的對象引用,一般是常量或靜態方法的使用。

    好比圖中,Activity使用了PolicyManager類的靜態方法 makeNewWindow() 建立了PhoneWindow對象,咱們說Acitivy 依賴PolicyManager 這個模塊,但它並無引用PoclicyManager的對象。

    依賴一般用一根單向虛線箭頭表示。

2. 時序圖

    經過時序圖,咱們能夠了解代碼的調用流程, 並能夠檢查調用過程當中可能產成的潛在問題,如死鎖等。

    時序圖能夠從兩個方向去看,縱向和橫向。

    縱向描述了一個對象在時間軸上所作的事情,一個方塊經過表明一個函數的調用。

    橫向則描述了各個對象之間的調用關係, 包括同步調用,異步調用,返回等等。

    此外,在時序圖中,咱們能夠給執行塊賦予不一樣的顏色,表明了他們分別運行在不一樣的進程或線程裏。

    下面就是一張時序圖的例子,它描述了Android中一個System server 進程啓動的過程, 圖中的粉紅色註釋列舉了從圖中咱們能夠獲知的一些信息。

 
     剛纔不是說從時序圖中能看出死鎖? 就這樣同樣圖?誇張了吧! 沒錯,看看下面一個例子吧!
 
 

    這是一個很簡單的例子,圖中有兩個線程,綠色是app線程,它經過調用MediaPlayer 對象的函數來控制播放器,這裏它作了兩件事,Start() 而後 Stop (). 而粉色部分表明Driver 線程,它經過回調函數告知Mediaplayer 一下底層的事件。也就是說Mediaplayer 是一個被兩個線程同時引用的對象,是一個共享的資源。

    想固然的,咱們用了一把鎖來保護它,防止他被同時使用產生衝突。因此,圖中,綠色的app在Stop()時候首先拿到了鎖。這時問題發生了,Stop()的過程可能會比較長,中途來了一個事件, 圖中黃色註釋的右方顯示了這個狀況,兩個顏色的長條重疊在一塊兒。這代表有資源衝突發生,也意味着潛在的死鎖風險。咱們假設Stop()的最終目的就是要析構VideoDecoder 對象,但此時,VideoDecoder調用的eventHandler() 在另一個線程還沒返回,理所固然的咱們須要等待它。不幸的是,這個時候死鎖發生了,如圖中紅色註釋所示。

    經過簡單的畫這麼一個圖,能夠很輕易的分析出一個死鎖的狀況。那怎麼解決它的,盡能夠的避免圖中不一樣顏色的條塊重疊在一塊兒。看看下面的解決方案


     這回,咱們取消了鎖的操做,經過添加一個新的線程(變成3個線程,3種顏色)Thread,將同步的調用變成異步,,交由Thread作後臺處理。
     所以圖中再也不有顏色塊重疊(異步調用產生的重疊不算), Stop()和EventHandler都很快返回(異步調用), 從而消除了死鎖的存在。
     這也是爲何Andriod 設計了Looper, MessageQueue 和 Handler 的異步消息處理機制,並在Framework 中大量的使用,由於Android 是個極其複雜的多線程/多進程應用環境,基於鎖的同步調用機制是難於保證徹底避免死鎖的發生。

    這下贊成了吧,時序圖對分析多線程的編程分析有很大的幫助。咱們應該在設計階段儘量的用類圖和時序圖來幫助咱們避免一些常見的問題,幫助咱們得出一個儘量好的設計。

3.  怎樣畫Android UML 圖?

    工具!必須依賴工具,市面上有太多的UML工具,你只須要找一款支持逆向工程的,即將代碼轉換成UML的數據結構,而後將類圖或時序圖一步步的繪製出來。

參考文章

http://www.cnblogs.com/samchen2009/p/3315999.html
相關文章
相關標籤/搜索