Android設(shè)計(jì)模式系列-單例模式
單例模式,可以說是GOF的23種設(shè)計(jì)模式中最簡單的一個(gè)。
這個(gè)模式相對于其他幾個(gè)模式比較獨(dú)立,它只負(fù)責(zé)控制自己的實(shí)例化數(shù)量單一(而不是考慮為用戶產(chǎn)生什么樣的實(shí)例),很有意思,是一個(gè)感覺上很干凈的模式,本人很喜歡這個(gè)模式。
android中很多地方都用到了單例模式,本文以輸入法管理者InputMethodManager為例,展開分析。
單例模式,Singleton Pattern,能夠以其特有的優(yōu)勢,替代系統(tǒng)中全局變量,應(yīng)用非常廣泛。
1.意圖
保證一個(gè)類僅有一個(gè)實(shí)例,并提供一個(gè)訪問它的全局訪問點(diǎn)。
熱門詞匯:單例 *** 私有構(gòu)造
2.結(jié)構(gòu)
android中有很多系統(tǒng)級別的全局變量,如時(shí)間,輸入法,賬戶,狀態(tài)欄等等,android中對這些都直接或者有些間接用到了單例模式。
以輸入法為例,把上圖修改為實(shí)際情況:
非常的簡單,但是有一點(diǎn),從上面我們也看到了synchronized關(guān)鍵字,在多線程的環(huán)境下,單例模式為了保證自己實(shí)例數(shù)量的***,必然會做并發(fā)控制。
類似這種線程安全的單例,跨進(jìn)程的單例,參數(shù)化的單例等等的情況,確實(shí)超出本文的范圍,而且都涉及到很多東西,是一個(gè)很大的話題,不好展開。
3. 代碼:
- public final class InputMethodManager {
- static final Object mInstanceSync = new Object();//同步
- //內(nèi)部全局***實(shí)例
- static InputMethodManager mInstance;
- //對外api
- static public InputMethodManager getInstance(Context context) {
- return getInstance(context.getMainLooper());
- }
- /**
- * 內(nèi)部api,供上面的外部api調(diào)用
- * @hide 系統(tǒng)隱藏的api
- */
- static public InputMethodManager getInstance(Looper mainLooper) {
- synchronized (mInstanceSync) {
- if (mInstance != null) {
- return mInstance;
- }
- IBinder b = ServiceManager.getService(Context.INPUT_METHOD_SERVICE);
- IInputMethodManager service = IInputMethodManager.Stub.asInterface(b);
- mInstance = new InputMethodManager(service, mainLooper);
- }
- return mInstance;
- }
- }
客戶端調(diào)用,比如contextimpl中的getSystemService()方法中如下調(diào)用:
- class ContextImpl extends Context{
- @Override
- public Object getSystemService(String name) {
- if (WINDOW_SERVICE.equals(name)) {
- //... ... 省略下面n個(gè)if,else if
- } else if (INPUT_METHOD_SERVICE.equals(name)) {
- //獲取輸入法管理者***實(shí)例
- return InputMethodManager.getInstance(this);
- } else if (KEYGUARD_SERVICE.equals(name)) {
- //... ... 省略下面n個(gè)if,else if
- } else if (ACCESSIBILITY_SERVICE.equals(name)) {
- //又見單例,無處不在
- return AccessibilityManager.getInstance(this);
- } else if (LOCATION_SERVICE.equals(name)) {
- //... ... 省略下面n個(gè)if,else if
- } else if (NFC_SERVICE.equals(name)) {
- return getNfcManager();
- }
- return null;
- }
- }
非常簡單,干凈的一個(gè)模式。
4.效果
(1).創(chuàng)建型模式。
(2).對***實(shí)例的受控訪問。
(3).避免全局變量污染命名空間。
(4).允許對操作和表示的精化。
(5).比類操作更靈活。