如何快速的寫一個單例

柴澤建_Jack發表於2016-09-26

釋出更新 9/27:改正了讀者指出的錯誤。謝謝大家!還有什麼錯誤和不足儘管指出!

本文中方法適用與Android StudioIntelliJ Idea

我們寫程式碼的時候經常要寫個單例,其實在Android Studio中可以快速寫一個單例的方法有很多。

1 從程式碼模版建立一個單例

1.1 從預設單例模版建立一個單例

File -> New -> Singleton

這是生成單例程式碼的一個例子。

public class Test {
    private static Test ourInstance = new Test();

    public static Test getInstance() {
        return ourInstance;
    }

    private Test() {
    }
}複製程式碼

謝謝讀者提醒!這裡寫錯了!這裡保留原文。下面正文更正!下面程式碼和模版程式碼同時更正,但因篇幅原因,程式碼保留原文了!

原文:這個單例有幾個缺點。getInstance沒有對ourInstance進行空判斷,所以可能返回null。如果加上空判斷,並在其內部如果例項化一個物件就又有一個問題,如果不同步的話可能產生多個物件。所以,Android Studio為我們提供的這個方法並不好。我希望的是這個樣子的:

上面單例是直接賦值的,但是通常,我們都是使用的時候才去賦值,所以通常情況下是下面這個樣子。

public class Test {
    private static Test instance ; 

    public static Test getInstance() {
        if (instance == null) {
            synchronized (Test.class) {
                if (instance == null) {
                    instance = new Test();
                }
            }
        }
        return instance;
    }

    private Test() {
    }
}複製程式碼

1.2 自定義單例模版

既然需求預設的需求不能實現我們的要求,那麼,去自定義單例模版。在 Preference->Editor->File and Code Templates可以找到建立各種File的模版。如圖:

我們選擇單例,然後在右邊的編輯區就可以編寫自己的程式碼模版。

那麼我這裡提供一套程式碼模版給大家,如果你不願意自己寫,直接把我的複製貼上過去就行了。

#if (${PACKAGE_NAME} && ${PACKAGE_NAME} != "")package ${PACKAGE_NAME};#end
#parse("File Header.java")
public class ${NAME} {
    private static ${NAME} instance ;

    public static ${NAME} getInstance() {
        if (instance == null) {
            synchronized(${NAME}.class){
                if (instance == null) {
                    instance = new ${NAME}();
                }
            }
        }
        return instance;
    }

    private ${NAME}() {
    }
}複製程式碼

然後我們使用這個模版再試一下:

就是我們想要的程式碼。怎麼樣?但是這樣並不總是符合我們的使用場景。我們有的時候,在建立一個類的時候並沒有想好它就是一個單例。有的時候是對一個現有的類的改造。但我們總不能再重新去建立一個吧。

那麼好。看下面。

2 從活動模版重構出一個單例

2.1 自定義活動模版

這個我在我之前的,Android Studio相見恨晚的操作錦集中已經講過一次了,但是為了防止沒有看過那篇文章的讀者我再講一遍。

自定義活動模版的入口:

Prefrence->Editor->Live Templates,下面就是整個介面的一些介紹。

例如我已經在user組中建立好了自己的singleton活動模版。如果是你們,可以按照下面步驟做:

  1. 先點選建立一個新的活動模版
  2. 然後自己起一個名字
  3. 描述可以不寫
  4. 編寫自己的活動模版程式碼
  5. 有必要的需要在Edit variables中編輯函式式

當然我已經編寫好了活動模版程式碼,我貼在這裡,你可以直接複製貼上到自己的裡面:

private static $SELECTION$ instance ;

private $CLASS_NAME$($param1$){
    $init$
}

public static $SELECTION$ getInstance($param1$){
    if (instance == null) {
        synchronized ($CLASS_NAME$.class){
            if (instance == null) {
                instance = new $CLASS_NAME$($param2$) ;
            }
        }
    }
    return instance ;
}複製程式碼

注意 下面一步很關鍵

複製完之後。點選Edit variables;在CLASS_NAME對應的後面一格填寫表示式className()。如圖。

好了大功告成!

2.2 使用自定義模版重構單例程式碼

首先說一下,在我們公司,JavaBean的賦值都是通過依賴注入的方式。幾乎每一個JavaBean都提供了一個介面,單例也是。當然我上面的活動模版也是針對這種情況編寫的,併相容不是依賴注入的情況。

那麼好我們看一個例子:

我們將一個現有的Test類改造成一個單例;

public class Test implements ITest {

    private static final String TAG = Test.class.getSimpleName();

    public Test(String test) {
        init(test);
    }

    private void init(String test) {
        Log.d(TAG, "init: " + test);
    }
}複製程式碼

我們的目標應該是將其改造成這樣:

public class Test implements ITest {

    private static final String TAG = Test.class.getSimpleName();

    private static ITest instance;

    private Test(String test) {
        init(test);
    }

    public static ITest getInstance(String test) {
        if (instance == null) {
            synchronized (Test.class) {
                if (instance == null) {
                    instance = new Test(test);
                }
            }
        }
        return instance;
    }

    private void init(String test) {
        Log.d(TAG, "init: " + test);
    }
}複製程式碼

OK,那麼看看使用我們的活動模版怎麼做吧!

  1. 輸入要返回的介面,或者類。(因為我們是依賴注入,所以我寫的介面,如果你不是這樣子,你就寫你要返回的類命就行了)
  2. 選中剛才輸入的名字。
  3. 使用Surround With,快捷鍵Alt+Command+T(如果你是windows,或者快捷鍵不是這個,看下圖,你可以雙擊shift鍵,輸入surround with檢視,如果你的紅框部分沒有東西,自己去keymap中去設定吧)
  4. 選擇我們寫好的singleton活動模版。就會生成好大部分程式碼。
  5. 然後跟著游標輸入建構函式中的引數,初始化的方法,getInstance中生成物件要傳入的引數即可。
  6. 這個時候報錯,沒有關係,因為之前的public構造方法沒有刪除。這一步就是刪除原來的public方法

那麼好,在錄製的時候我故意在關鍵的地方放慢了速度,否則可以更快。這樣是不是可以很快的改造一個單例類了!

3 結束語

我發現我的文章總是被轉成圖片在微博中轉發,在這裡非常感謝大家的賞識。我也希望自己可以給大家分享更多精彩的文章。其實自己在分享的同時也收穫了很多。

但是轉成圖片,就看不到動圖的效果了。有些操作的演示還是很依賴動圖展示的。不過我看轉發我文章的人都會附上原文連結,我在這裡,非常建議大家去看原文。我保證原文更加精彩。

如果你只看到了圖片,那也無所謂了,我的文章暫時也沒有維權呢,那些不帶原文連結和作者資訊的人,他們轉就轉吧,他們開心就好。如果對我們文章感興趣可以到 掘金 中搜尋作者,柴澤建_Jack,就可以檢視我的文章了。

“作者好菜連個連結都不會放嗎?”

“如果生成了圖片你們會去敲連結嗎?”

“會!”

哈哈!我就是“一個逗逼,一個Android開發者,一個持續分享技術乾貨的小浪逼。”

相關閱讀

我其它可能與本文相關的文章。

教你把Java Bean擼成串的最快方法-自定義setter生成指令碼

讓你的Android Studio性感起來--Sexy Editor

Android Studio相見恨晚的操作錦集

相關文章