設計模式執行個體學習-單例模式(Android中的使用情境)

來源:互聯網
上載者:User

標籤:設計模式   單例模式   java   android   

1.設計模式執行個體-單例模式

單例模式,故名思議,是指在一個類中通過設定靜態使得其僅創造一個唯一的執行個體。這樣設定的目的是滿足開發人員的希望——這個類只需要被執行個體化建立一次,同時因為其為靜態緣故,載入的速度也應該快於正常執行個體化一個類的速度(理論上)。

在Android開發中,當我們需要建立一個Fragment的時候常常會用到這樣的模式,沒有代碼的學習是虛無的,接下來亮代碼學習:

public class SelectFrame extends Fragment {  private final static String selectFrameKey = "SFKey";  private static SelectFrame mSelectFrame;  private ArrayList<String> frameList;  public static SelectFrame getInstance(ArrayList<String> frameList){    if (mSelectFrame == null) {      mSelectFrame = new SelectFrame();    }    Bundle bundle = new Bundle();    bundle.putStringArrayList(selectFrameKey, frameList);    mSelectFrame.setArguments(bundle);    return mSelectFrame;  }
......


這是我在一個Fragment類裡面定義的其中一部分,首先必須要定義一個自身的靜態mSelectFrame。然後通過一個靜態方法 getInstance()來執行個體化這個mSelectFrame,很明顯,這裡通過判斷其是否為空白的方式,使得每一次我們使用getInstance的時候都返回的是同一個對象mSelectFrame。

getInstance方法中有時我們也會放入一些我們需要傳遞的參數,比如我這個方法中放入了一個List對象,然後直接在裡面用Bundle裝載這個List對象,原本我們可能是在外部來做這些操作的,然而現在卻直接通過這個方法將資料傳入的操作整合到了這個Fragment中,即減少了外部Activity的邏輯代碼,也使得這個Fragment在複用的時候操作更方便。(再通過setArguments的方法儲存資料)。

接下來看我們的onCreateView方法:

  @Override  public View onCreateView(LayoutInflater inflater,      @Nullable ViewGroup container, @Nullable Bundle savedInstanceState) {    view = inflater.inflate(R.layout.select_frame_fragment, container, false);    Bundle bundle = mSelectFrame.getArguments();    frameList = bundle.getStringArrayList(selectFrameKey);}
這裡我們就將從前面getInstance中setArguments儲存下來的資料通過Fragment的getArguments方法重新將資料讀取出來。這樣就完成了我們的目的。

接下來就是在Activity中建立我們這個Fragment對象了:

    selectFrameFrag = SelectFrame.getInstance(nameFrameThumbnail);    fm.beginTransaction().add(R.id.fragment_frame_container, selectFrameFrag).commit();
(fm是FragmentManager..)

這樣就OK了。

2.單例模式的分類

單例模式有兩種建立方式,分別為餓漢式和懶漢式。

餓漢式,故名思議,很餓,在一開始就直接建立了這個對象。

懶漢式,顧名思義,很懶,只有在你要調用它的時候,通過自己寫的方法裡面來對他執行個體化。剛剛上面那個例子就是懶漢式的。

也許這麼說你會有一點不明白(其實應該沒有人不明白吧= =),然後其實只要看代碼的這個地方:

  private static SelectFrame mSelectFrame;

上面這個代碼,這裡一開始定義自身的靜態時,沒有執行個體化它,那麼就是個懶漢.然後只有在我調用getInstance方法的時候,才在裡面對他進行執行個體化(new SelectFrame()).

然後我們再看看餓漢:


  private static SelectFrame mSelectFrame = new SelectFrame();

在定義的時候就已經執行個體化了.

3.單例模式的安全執行緒問題

沒錯,單例模式畢竟就是像上面講的這麼簡單。但需要注意的是,單例模式中的餓漢式是安全執行緒的,而懶漢式是線程不安全的,我們一般會再懶漢式的getInstance方法中通過synchronized上鎖。類似於這樣:

    if (mSelectFrame == null) {      synchronized (SelectFrame.class) {        if (mSelectFrame == null) {          mSelectFrame = new SelectFrame();        }      }    }

有人說為什麼要用兩個if XX == null。這裡是因為提高效率,只有一個也是可以的,但效率上大大減低,因為不是每一次調用的時候我們要判斷他是否同步,應該是如果判斷當前為null的話,我們就直接不讓他進入了,不需要判斷是否同步。只有滿足第一個條件的時候,我們才需要用鎖來判斷它是否安全執行緒。(這裡的意思也是說明if一條語句的判斷速度當然比synchronized (SelectFrame.class)快。。)


另外,在我們使用單例模式的時候,有些人會去私人化這個類的構造方法,使得這個類只能通過自己寫的getInstance()來建立。類似於這樣:

  private SelectFrame() {    // 並不需要做什麼,只需要將這個外面的public改成private就好了=。=  }

嗯嗯,這麼一來外部就只能按我要求的方法來建立這個對象了.

在這裡也基本將單例模式的使用基本講完了,接下來還會繼續寫其他的設計模式的使用,如果有涉及到Android上的都會儘力用Android上的例子來講,加深印象。


Make Life Get Better.

著作權聲明:本文為博主原創文章,未經博主允許不得轉載。

設計模式執行個體學習-單例模式(Android中的使用情境)

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.