Nutz 設計模式應用 --- 單例模式

在IOC容器中, 所有的對象默認都是單例, 我們只需要把對象加載到IOC容器中即可.

nutz demo:

@IocBean
public class SingletonDemo {

}

public class SingletonDemoTest {

    private static Ioc ioc;

    @BeforeClass
    public static void setUp() throws Exception {

        ioc = new NutIoc(new AnnotationIocLoader("me.lihongjie"));
    }


    @Test
    public void ShouldGetSameInstance() throws Exception {
        Assert.assertThat(ioc.get(SingletonDemo.class), Is.is(ioc.get(SingletonDemo.class)));
    }
}

就這樣一個簡單的單例模式就實現了, 對於開發來說省卻了不少樣板代碼(雙檢查鎖), 對於學習來說, 我仍然希望能夠自己實現一個單例模式.

學習最重要的是一個推導以及整理的過程, 這樣才能夠完善自己的思維模式, 所以下面的代碼不是網絡上隨手複製的, 而是一步步完善出來的.

step 1 : 非單例模式

public class SingletonDemo {

    public SingletonDemo() {

    }
}

step 2: 封裝: 封裝我們不希望外界使用的關鍵字 : new

public class SingletonDemo {

    // 封裝 new 之後無法直接實例化對象, 只能使用類方法
    public static SingletonDemo newInstance(){
        return new SingletonDemo();
    }

    public SingletonDemo() {

    }
}

step 3 : 修改封裝的內部實現, 使其單例化:

public class SingletonDemo {

    private static SingletonDemo instance = new SingletonDemo();

    // 封裝 new 之後無法直接實例化對象, 只能使用類方法
    public static SingletonDemo newInstance(){
        return instance;
    }

    public SingletonDemo() {

    }
}

step 4: 優化單例實現, 使其懶加載:

public class SingletonDemo {

    private static SingletonDemo instance;

    // 封裝 new 之後無法直接實例化對象, 只能使用類方法
    public static SingletonDemo newInstance(){
        // 只有在第一次調用時纔會加載
        if (instance == null) {
            return new SingletonDemo();
        }
        return instance;
    }

    public SingletonDemo() {

    }
}

step 5: 優化懶加載單例實現, 使其線程安全:

public class SingletonDemo {

    private static SingletonDemo instance;

    // 封裝 new 之後無法直接實例化對象, 只能使用類方法
    // 線程同步
    public static synchronized SingletonDemo newInstance() {
        if (instance == null) {
            return new SingletonDemo();
        }
        return instance;
    }

    public SingletonDemo() {

    }
}

step 6: 優化線程安全版懶加載, 縮小線程同步範圍

public class SingletonDemo {

    private static SingletonDemo instance;

    // 封裝 new 之後無法直接實例化對象, 只能使用類方法
    // 線程同步
    public static SingletonDemo newInstance() {
        if (instance == null) {
        // 只同步if 代碼塊, 優化性能
            synchronized (SingletonDemo.class) {
                if (instance == null) {

                    return new SingletonDemo();
                }
            }
        }
        return instance;
    }

    public SingletonDemo() {

    }
}

具體的代碼含義就不細說了, 這方面有許多博客都可以參考, 關鍵是單例模式實現的推導過程:

  1. 如果你只需要簡單的單例模式或者只想學習單例模式, 那麼到step 3 就足夠了, 因爲後面的內容是優化, 不是必須, 不要過早優化.
  2. 模式的演化是伴隨着一些需求的, 比如說: 懶加載, 多線程, 而這些演化並不是模式的核心內容, 以多線程爲例, 如果你學會了簡單的Java多線程模式然後自己優化也可以把step 3 後面的實現完成.
發佈了23 篇原創文章 · 獲贊 0 · 訪問量 1755
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章