成人午夜视频全免费观看高清-秋霞福利视频一区二区三区-国产精品久久久久电影小说-亚洲不卡区三一区三区一区

創(chuàng)建型模式:單例模式-創(chuàng)新互聯(lián)

文章首發(fā):
創(chuàng)建型模式:單例模式

讓客戶滿意是我們工作的目標(biāo),不斷超越客戶的期望值來自于我們對這個行業(yè)的熱愛。我們立志把好的技術(shù)通過有效、簡單的方式提供給客戶,將通過不懈努力成為客戶在信息化領(lǐng)域值得信任、有價值的長期合作伙伴,公司提供的服務(wù)項目有:申請域名、虛擬空間、營銷軟件、網(wǎng)站建設(shè)、盈江網(wǎng)站維護(hù)、網(wǎng)站推廣。

創(chuàng)建型模式:單例模式

簡介

姓名:單例模式

英文名:Singleton Pattern

價值觀:我的生活我主宰(只允許自己實例化,不愿意被其他對象實例化)

個人介紹

Ensure a class has only one instance, and provide a global point of access to it.(確保某一個類只有一個實例,而且自行實例化并向整個系統(tǒng)提供這個實例。)
(來自《設(shè)計模式之禪》)

這里的關(guān)注點(diǎn)有 3 個,分別是:

  1. 只有一個實例
  2. 自行實例化(也就是主動實例化)
  3. 向整個系統(tǒng)提供這個實例

你要的故事

我們腦洞大開來用一個故事講解一番。

小明家里有一輛小汽車,具體什么牌子就不知道了,咱也不關(guān)注,反正他家里就這么一輛車,小明比較懶,只要一出門都會開車,例如去旅游、去學(xué)校、去聚會都會開車去。下面模擬小明出去的場景。

class Car {
    public void run() {
        System.out.println("走。。。。");
    }
}

class XiaoMing {
    public Car travel() {
        System.out.println("小明去旅游");
        Car car = new Car();
        car.run();
        return car;
    }

    public Car goToSchool() {
        System.out.println("小明去學(xué)校");
        Car car = new Car();
        car.run();
        return car;
    }

    public Car getTogether() {
        System.out.println("小明參加聚會");
        Car car = new Car();
        car.run();
        return car;
    }
}

public class SingletonErrorTest {

    public static void main(String[] args) {
        XiaoMing xiaoMing = new XiaoMing();
        Car car1 = xiaoMing.travel();
        Car car2 = xiaoMing.goToSchool();
        Car car3 = xiaoMing.getTogether();
    }

}

上面小汽車只有一個方法,就是走。小明去旅游、去學(xué)校、參加聚會都開著他唯一的一輛汽車車去。是不是有人有疑問?為什么每個方法都返回 Car 對象?其實只是想在下面做一次檢查,檢查小明去旅游、去學(xué)校和參加聚會的車是不是同一輛。下面是檢查代碼:

System.out.println("car1 == car2 ? " + (car1 == car2));
System.out.println("car2 == car3 ? " + (car2 == car3));

最終結(jié)果是啥?很明顯是 2 個 false。小明去旅游、去學(xué)校和參加聚會的車都不相同,小明不是只有 1 輛車?關(guān)鍵在于 Car car = new Car();這一句代碼,其實這一句是創(chuàng)建一輛車,每次都重新創(chuàng)建一輛。那應(yīng)該怎么實現(xiàn)小明只有一輛車呢?這時候就引入了單例模式

上面我們說到了單例模式需要具備的 3 個點(diǎn):只有 1 個實例,很顯然,上面的代碼不止 1 個實例,而是有 3 個 Car 實例;自行實例化,Car 本身沒有主動實例化,而是在小明需要用到的時候才實例化;向整個系統(tǒng)提供這個實例,因為 Car 沒有主動實例化,所以它沒法向外部暴露提供自己出來。

我們的代碼完全不符合單例模式的要求。我們要通過修改,使之符合單例模式的 3 個要點(diǎn)。首先需要實現(xiàn)的是第 2 點(diǎn),把 Car 實例化從小明轉(zhuǎn)為 Car 本身,如下代碼

class Car1{

    private static Car1 car1 = new Car1();

    private Car1() {

    }

    public void run(){
        System.out.println("走。。。。");
    }
}

上面代碼使用 private 修飾構(gòu)造方法,使得 Car1 不能被其他使用方實例化,通過 Car1 car1 = new Car1();主動實例化自己。

接下來再實現(xiàn)第 3 點(diǎn),向整個系統(tǒng)暴露這個實例,也就是暴露它自己。每個使用方都調(diào)用 Car1.getInstance()方法來獲取實例。

class Car1{

    private static Car1 car1 = new Car1();

    public static Car1 getInstance() {
        return car1;
    }

    private Car1() {

    }

    public void run(){
        System.out.println("走。。。。");
    }
}

上面代碼就實現(xiàn)了單例模式的 2 和 3 要點(diǎn),第 1 要點(diǎn)要怎么實現(xiàn)呢?告訴你,不用實現(xiàn),只要滿足了 2 和 3 要點(diǎn)就可以,第 1 要點(diǎn)是用來檢驗是否是單例模式的好思路。我們檢驗一下

class Car1{

    private static Car1 car1 = new Car1();

    public static Car1 getInstance() {
        return car1;
    }

    private Car1() {

    }

    public void run(){
        System.out.println("走。。。。");
    }
}

class XiaoMing1 {
    public Car1 travel() {
        System.out.println("小明去旅游");
        Car1 car = Car1.getInstance();
        car.run();
        return car;
    }

    public Car1 goToSchool() {
        System.out.println("小明去學(xué)校");
        Car1 car = Car1.getInstance();
        car.run();
        return car;
    }

    public Car1 getTogether() {
        System.out.println("小明參加聚會");
        Car1 car = Car1.getInstance();
        car.run();
        return car;
    }
}

public class SingletonRightHungryTest {

    public static void main(String[] args) {
        XiaoMing1 xiaoMing1 = new XiaoMing1();
        Car1 car1 = xiaoMing1.travel();
        Car1 car2 = xiaoMing1.goToSchool();
        Car1 car3 = xiaoMing1.getTogether();

        System.out.println("car1 == car2 ? " + (car1 == car2));
        System.out.println("car2 == car3 ? " + (car2 == car3));
    }

}

上面代碼最后兩行打印出來的結(jié)果是啥?是我們想要的:2 個 true。說明小明這幾次外出開的車都是同一輛。這是最簡單的單例模式的實現(xiàn)方式,我們經(jīng)常稱作餓漢式單例模式。為什么起這么古怪的名字呢?其實和對應(yīng)的懶漢式單例模式有關(guān),這是 2 個實現(xiàn)方式的差別,餓漢式單例模式實現(xiàn)方式在類加載到內(nèi)存的時候,就創(chuàng)建好對象了,而懶漢式則是在第一次使用的時候才創(chuàng)建對象,也就是把創(chuàng)建對象的時機(jī)從加載延遲到第一次使用,所以才有懶餓之分。

下面我們來看怎么實現(xiàn)懶漢式單例模式。先描述一下場景:小明還沒有汽車,他也不知道什么時候要買汽車,突然某一天,他想去旅游,覺得是時候買輛車了,然后他就買車去旅游了,旅游回來又開車去學(xué)校和參加聚會。

class Car2{

    private static Car2 car2;

    public static synchronized Car2 getInstance() {
        if (null == car2) {
            System.out.println("買車?yán)病??!?);
            car2 = new Car2();
        }
        return car2;
    }

    private Car2() {

    }

    public void run(){
        System.out.println("走。。。。");
    }
}

class XiaoMing2
{
    public Car2 travel() {
        System.out.println("小明去旅游");
        Car2 car = Car2.getInstance();
        car.run();
        return car;
    }

    public Car2 goToSchool() {
        System.out.println("小明去學(xué)校");
        Car2 car = Car2.getInstance();
        car.run();
        return car;
    }

    public Car2 getTogether() {
        System.out.println("小明參加聚會");
        Car2 car = Car2.getInstance();
        car.run();
        return car;
    }
}

public class SingletonRightLazyTest {

    public static void main(String[] args) {
        XiaoMing2 xiaoMing2 = new XiaoMing2();
        Car2 car1 = xiaoMing2.travel();
        Car2 car2 = xiaoMing2.goToSchool();
        Car2 car3 = xiaoMing2.getTogether();

        System.out.println("car1 == car2 ? " + (car1 == car2));
        System.out.println("car2 == car3 ? " + (car2 == car3));
    }

}

小明去旅游
買車?yán)?。?!?走。。。。
小明去學(xué)校
走。。。。
小明參加聚會
走。。。。
car1 == car2 ? true
car2 == car3 ? true

上面附帶了打印出來的結(jié)果,小明要去旅游的時候,才去買車。這就是懶漢式單例模式的實現(xiàn)方式。

要注意懶漢式單例模式有個很關(guān)鍵的一點(diǎn)就是 getInstance() 方法帶上了 synchronized,這個是為什么呢?

首先得了解關(guān)鍵字 synchronized 的作用是什么:用于修飾執(zhí)行方法同步,也就是說多線程并發(fā)的情況下,在一個時間點(diǎn),只允許一個線程執(zhí)行這個方法。

不加上這個會有什么結(jié)果?在多線程并發(fā)情況下,如果有 2 個線程同時執(zhí)行到 if(null == car2),那么都判斷為 true,這時 2 個線程都會執(zhí)行 car2 = new Car2(),這樣子就不是單例了。

總結(jié)

單例模式可以說是設(shè)計模式中最簡單的一個,也是在工作中很多場景下經(jīng)常用到的,比如:項目的配置文件加載、各種工具類等等。我們對于單例模式最重要的一點(diǎn)就是要考慮多線程并發(fā),沒有考慮這點(diǎn)就容易引發(fā)單例對象不單例的情況。而單例給我們帶來大的好處就是節(jié)約內(nèi)存。

上面實現(xiàn)的兩種方法是單例模式中最最最簡單的 2 種實現(xiàn),相信也是用得最多的實現(xiàn)方式。網(wǎng)上有不少網(wǎng)友分享了單例模式的很多種實現(xiàn)方法,大家也可以去了解,在了解之前務(wù)必已經(jīng)搞懂文中這 2 種最簡單的實現(xiàn)方式,不然會頭暈的。

希望文章對您有所幫助,設(shè)計模式系列會持續(xù)更新,感興趣的同學(xué)可以關(guān)注公眾號LieBrother,第一時間獲取文章推送閱讀,也可以一起交流,交個朋友。

另外有需要云服務(wù)器可以了解下創(chuàng)新互聯(lián)scvps.cn,海內(nèi)外云服務(wù)器15元起步,三天無理由+7*72小時售后在線,公司持有idc許可證,提供“云服務(wù)器、裸金屬服務(wù)器、高防服務(wù)器、香港服務(wù)器、美國服務(wù)器、虛擬主機(jī)、免備案服務(wù)器”等云主機(jī)租用服務(wù)以及企業(yè)上云的綜合解決方案,具有“安全穩(wěn)定、簡單易用、服務(wù)可用性高、性價比高”等特點(diǎn)與優(yōu)勢,專為企業(yè)上云打造定制,能夠滿足用戶豐富、多元化的應(yīng)用場景需求。

網(wǎng)站名稱:創(chuàng)建型模式:單例模式-創(chuàng)新互聯(lián)
網(wǎng)站地址:http://jinyejixie.com/article48/ddedhp.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供定制網(wǎng)站網(wǎng)站策劃、網(wǎng)站制作網(wǎng)站導(dǎo)航、靜態(tài)網(wǎng)站域名注冊

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

成都做網(wǎng)站
江孜县| 武冈市| 绥中县| 凤城市| 十堰市| 休宁县| 二连浩特市| 新巴尔虎左旗| 四会市| 长葛市| 盱眙县| 博湖县| 镶黄旗| 石阡县| 驻马店市| 横峰县| 进贤县| 桐梓县| 浮山县| 余姚市| 广东省| 宁安市| 乐昌市| 明星| 株洲县| 交城县| 闸北区| 宁海县| 浙江省| 肥城市| 垫江县| 阿拉尔市| 灌南县| 南京市| 青神县| 南充市| 洪湖市| 阿拉善盟| 福建省| 潍坊市| 兰坪|