面向對象編程內功心法系列七(聊一聊單例模式)

1.引子

說起設計模式,做過開發的你一定不會感到陌生,甚至隨口都能說上幾個。比如單例設計模式、工廠設計模式、建造者設計模式、模板設計模式、策略設計模式、裝飾者設計模式、責任鏈設計模式、觀察者設計模式、代理設計模式、適配器設計模式。

你看我一口氣就列舉了10種常見的設計模式,寓意爲十全十美,事實上在gof設計模式中,一共有23種設計模式,細分類爲創建型、結構型、行爲型設計模式。每一種設計模式都是無數前輩們經驗智慧的結晶,都爲了解決某一問題域而誕生,實實在在。

今天開始,我想推薦你一起來學習設計模式,不管我們是前端開發工程師,還是後端開發工程師,我覺得都有必要。一來通過學習理解設計模式,有助於提升我們的設計編碼內功;二來通過學習理解設計模式,有助於我們在尋找工作機會的時候,與面試官用愉快的心情聊天,不至於尬聊;三嘛當然則是設計模式是我們通往高級工程師,架構師的必備基本技能之一。

那麼讓我們一起開始吧,今天我們先來聊一聊單例設計模式。

2.案例

2.1.什麼是單例設計模式

單例設計模式,重點兩個字是單例。我們用更直觀的描述則是說,一個類,在整個應用系統中,有且僅有一個實例對象

有關單例設計模式的應用場景,我們試想這樣一個需求:全局唯一。每個應用系統都有配置文件,通過配置文件統一配置整個應用環境信息,比如數據庫連接信息、緩存redis連接信息等。

在系統啓動加載的時候,需要將配置文件內容讀取解析存儲到內存。從整個應用的角度,配置信息獨一無二,我們只需要存儲一份就夠了。這樣帶來的好處有,一來方便數據一致性的維護,如果需要修改更新配置信息,只需要維護一份;而來只存儲一份,即節省了內存資源開銷,省資源。

你看這就是單例設計模式的應用場景,以及它所帶來的收益,很好理解對吧。理解了單例設計模式,我們再來看一下如何通過代碼實現,talk is cheap, show me you code!

關於單例設計模式,有兩種實現方式:餓漢式、以及懶漢式。我們都一起來看一下如何實現。都比較簡單,我就直接上代碼了,代碼中我配備了相關注釋,相信你一看就都能明白。

2.2.餓漢式實現單例設計模式

/**
 * 單例設計模式:
 * 1.一個類,在整個系統中有且僅有一個對象,稱爲單例設計模式
 * 2.比如:配置文件信息,在整個系統中只需要一份配置文件,便於實現信息一致性維護,
 * 同時節省內存資源
 * 3.單例設計模式實現方式:餓漢式,懶漢式
 *
 * @author ThinkPad
 * @version 1.0
 * @date 2021/2/21 16:26
 */
public class HungrySingleton {

    public static void main(String[] args) {
        System.out.println("餓漢式實現IdGenerator 生成器:"
                + IdGenerator.getInstance().getId());

    }

    /**
     * 單例設計模式,餓漢式實現Id生成器
     */
    static class IdGenerator{
        private AtomicInteger id = new AtomicInteger(0);
        /**
         * 餓漢式,創建對象線程安全
         */
        private static IdGenerator instance = new IdGenerator();

        /**
         * 構造方法私有化
         */
        private IdGenerator(){}

        /**
         * 提供公有的靜態方法,獲取實例
         * @return
         */
        public static IdGenerator getInstance(){
            return instance;
        }

        public int getId(){
            return id.incrementAndGet();
        }

    }

}

2.3.懶漢式實現單例設計模式

/**
 * 單例設計模式:
 * 1.一個類,在整個系統中有且僅有一個對象,稱爲單例設計模式
 * 2.比如:配置文件信息,在整個系統中只需要一份配置文件,便於實現信息一致性維護,
 * 同時節省內存資源
 * 3.單例設計模式實現方式:餓漢式,懶漢式
 *
 * @author ThinkPad
 * @version 1.0
 * @date 2021/2/21 16:43
 */
public class LazySingleton {

    public static void main(String[] args) {
        System.out.println("懶漢式實現IdGenerator 生成器:"
                + IdGenerator.getInstance().getId());
    }

    /**
     * 單例設計模式,懶漢式實現Id生成器
     */
    static class IdGenerator{
        private AtomicInteger id = new AtomicInteger(0);
        /**
         * 懶漢式,支持延遲加載,需要考慮創建對象時線程安全問題
         * volatile關鍵字,保障內存可見性,及禁止指令重排序
         */
        private static volatile IdGenerator instance;

        /**
         * 構造方法私有化
         */
        private IdGenerator(){}

        /**
         * 提供公有的靜態方法,獲取實例,兼顧線程安全與性能
         * 通過synchronized,與雙重檢測(double check)保障線程安全
         * @return
         */
        public static IdGenerator getInstance(){
            if(instance == null){
                synchronized (IdGenerator.class){
                    if(instance == null){
                        instance = new IdGenerator();
                    }
                }
            }

            return instance;
        }

        public int getId(){
            return id.incrementAndGet();
        }
    }
}

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章