• <tr id="yyy80"></tr>
  • <sup id="yyy80"></sup>
  • <tfoot id="yyy80"><noscript id="yyy80"></noscript></tfoot>
  • 99热精品在线国产_美女午夜性视频免费_国产精品国产高清国产av_av欧美777_自拍偷自拍亚洲精品老妇_亚洲熟女精品中文字幕_www日本黄色视频网_国产精品野战在线观看 ?

    單例設(shè)計模式的研究與實現(xiàn)

    2017-10-12 03:23:08葛萌歐陽宏基陳偉咸陽師范學(xué)院計算機學(xué)院陜西咸陽712000
    微型電腦應(yīng)用 2017年9期
    關(guān)鍵詞:枚舉序列化設(shè)計模式

    葛萌, 歐陽宏基, 陳偉(咸陽師范學(xué)院計算機學(xué)院, 陜西 咸陽 712000)

    單例設(shè)計模式的研究與實現(xiàn)

    葛萌, 歐陽宏基, 陳偉
    (咸陽師范學(xué)院計算機學(xué)院, 陜西 咸陽 712000)

    單例設(shè)計模式能夠保證某個類的對象在內(nèi)存中只有唯一的實例,該實例易于被外界訪問并節(jié)約系統(tǒng)資源。分析了單例模式的角色構(gòu)成和創(chuàng)建要點,分別從餓漢式、懶漢式、雙重驗證式、類加載式、枚舉式等5個方面闡述了單例模式的實現(xiàn)過程,總結(jié)了5種形式的優(yōu)缺點和應(yīng)用場景。將單例模式應(yīng)用到JDBC數(shù)據(jù)庫開發(fā)中,設(shè)計了一個JDBC工具類,為單例模式的實際應(yīng)用提供了一定的參考。

    單例模式; 設(shè)計模式; JDBC; 類加載; 枚舉

    Abstract: The singleton design pattern ensures that one class has only one object instance in memory, the instance is easy to be accessed by the outside world and save system resources. The role composition and the key points of the singleton pattern are analyzed,the implementation process of the singleton pattern is described from five aspects of hungry type, lazy type, double authentication type, class loading type and enumeration type. Then it summarizes the advantages and disadvantages of those five types, and their application scenarios. The singleton pattern is applied to the database development with JDBC, and a JDBC tool class is designed. It provides a reference for the practical application of the singleton pattern.

    Keywords: singleton pattern; design pattern; JDBC; class loading; enumeration

    0 引言

    在利用面向?qū)ο蠹夹g(shù)進行應(yīng)用系統(tǒng)開發(fā)中合理使用設(shè)計模式,能夠獲得靈活的應(yīng)用架構(gòu)、良好的擴展性和較高的復(fù)用率。設(shè)計模式是一組精心設(shè)計的類和接口的組合,包含若干角色,每個類或接口充當(dāng)一種角色承擔(dān)一個職責(zé)。設(shè)計模式通常在某個應(yīng)用場景下使用,它

    為某種重復(fù)出現(xiàn)的問題提供一種最佳的指導(dǎo)方針和解決方案。GOF等人總結(jié)了軟件開發(fā)中使用頻率最高的23種設(shè)計模式,并根據(jù)模式的目的將它們分為三類:創(chuàng)建型、結(jié)構(gòu)型和行為型。創(chuàng)建型模式主要用于創(chuàng)建對象;結(jié)構(gòu)型模式用于處理類或?qū)ο蟮慕M合;行為型模式主要用于描述類或?qū)ο笕绾谓换ゲ⒎峙湄?zé)任。每個模式都包含四個關(guān)鍵的要素:模式名稱、問題、解決方案和效果[1]。

    單例設(shè)計模式是使用最為頻繁的一種創(chuàng)建型模式,它的主要思想是:確保某個類在內(nèi)存中只有一個對象,這個對象的創(chuàng)建由所屬類自身負(fù)責(zé),無論其它任何對象如何調(diào)用,都只能操作這個唯一的對象。因此,合理的使用單例模式能夠?qū)p少對象的創(chuàng)建次數(shù)并區(qū)分對象創(chuàng)建的責(zé)任,從而減少內(nèi)存的消耗,提高復(fù)用性。本文首先介紹了單例設(shè)計模式的角色構(gòu)成與實現(xiàn)要點,然后從餓漢式、懶漢式、雙重驗證式、類加載式、枚舉式等5個方面分析了單例模式的實現(xiàn)并給出了示例代碼,從線程安全、延遲加載、調(diào)用效率等幾個方面對5種實現(xiàn)方式進行了對比分析。最后,將單例模式應(yīng)用到JDBC數(shù)據(jù)庫操作中,設(shè)計了一個JDBC工具類。

    1 單例設(shè)計模式分析

    單例設(shè)計模式只包含一個角色,即單例類,如圖1所示[2]。

    圖1 單例模式結(jié)構(gòu)圖

    從類的定義角度考慮,創(chuàng)建單例類必須滿足三個要素:首先,在其內(nèi)部包含一個自身類型的靜態(tài)成員,作為外部共享的唯一實例;其次,只有唯一的構(gòu)造方法且訪問權(quán)限為私有,避免外部對象通過new關(guān)鍵字對其實例化。最后,提供一個公有的靜態(tài)getInstance()工廠方法,用來獲取靜態(tài)的自身成員,這個工廠方法作為訪問這個唯一對象的全局入口。

    2 單例模式的實現(xiàn)方式

    2.1 餓漢式

    如示例代碼1所示:

    示例代碼1

    public class SingletonClass {

    private static final SingletonClass instance=new SingletonClass();

    private SingletonClass (){}

    public static SingletonClass getInstance(){

    return instance;}}

    從示例代碼1可以看出,該類中有一個靜態(tài)成員instance,該成員在類加載時就被創(chuàng)建生成實例對象,final關(guān)鍵字確保該對象不被自身所修改。唯一的構(gòu)造方法是私有訪問權(quán)限,確保了外部類無法創(chuàng)建SingletonClass的對象;同時該構(gòu)造方法對子類不可見,也就保證不能通過繼承的方式來創(chuàng)建SingletonClass的對象。獲取唯一實例的方式是調(diào)用靜態(tài)getInstance()方法。由于這個唯一的對象是在類加載的時候創(chuàng)建,因此稱為餓漢式。由于類加載器是線程安全的,所以生成的單例對象也是線程安全的,但此方式不能做到對單例對象的延遲加載。延遲加載是節(jié)省內(nèi)存的一種有效手段,強調(diào)在使用某個對象的時候再創(chuàng)建該對象,避免提前創(chuàng)建而長時間又不使用該對象的情況[3-4]。

    2.2 懶漢式

    如示例代碼2所示:

    示例代碼2

    public class SingletonClass{

    private static SingletonClass instance=null;

    private SingletonClass (){}

    public static synchronized SingletonClass getInstance(){

    if(instance==null){

    instance=new SingletonClass();

    }

    return instance;

    }}

    從示例代碼2可以看出,在類加載時并不創(chuàng)建單例對象,而是在調(diào)用getInstance()方法時判斷單例對象是否存在,如果不存在再創(chuàng)建并返回該對象的引用。由于將單例對象的創(chuàng)建延遲到使用時才創(chuàng)建,所以稱為懶漢式??紤]到多線程環(huán)境下的線程同步問題,在靜態(tài)方法getInstance()前加入synchronized 關(guān)鍵字,確保多線程環(huán)境下單例對象只創(chuàng)建一次。懶漢式做到了延遲加載,但每次在調(diào)用getInstance()方法時都需要線程同步,調(diào)用效率較低。

    2.3 雙重驗證式

    如示例代碼3所示:

    示例代碼3

    public class SingletonClass{

    private static SingletonClass instance=null;

    private SingletonClass(){}

    public static SingletonClass getInstance(){

    //第一次判斷單例對象是否已經(jīng)存在

    if(instance==null){

    synchronized(SingletonClass.class)

    {

    //第二次判斷單例對象是否已經(jīng)存在

    if(instance==null){

    instance=new SingletonClass();

    } }

    return instance;

    }}

    雙重驗證方式中,將獲取單例對象方法的同步機制移到了方法體內(nèi),避免每次調(diào)用getInstance()方法就執(zhí)行同步。首先判斷單例對象是否已經(jīng)被創(chuàng)建,如果沒有創(chuàng)建,申請對單例類的Class對象加鎖,在同步塊內(nèi)再次判斷單例對象是否已經(jīng)被創(chuàng)建,如果沒有才創(chuàng)建單例對象。在同步塊內(nèi)對單例對象是否存在進行第二次判斷,可以避免多個線程都進入到第一次判斷為true的分支中,從而造成單例對象的多次創(chuàng)建。雙重驗證方式實現(xiàn)了單例對象的延遲加載,在getInstance()方法調(diào)用時只有在創(chuàng)建單例對象時需要同步,一旦創(chuàng)建后,就不再進行同步,提高了調(diào)用效率。

    2.4 靜態(tài)內(nèi)部類式

    如示例代碼4所示:

    示例代碼4

    public class SingletonClass{

    private SingletonClass(){}

    private static class SingletonClassHolder{

    private static final SingletonClass instance=new SingletonClass();

    }

    public static SingletonClass getInstance(){

    return SingletonClassHolder.instance;} }

    在SingletonClass中定義了一個私有的靜態(tài)內(nèi)部類SingletonClassHolder,其中的instance就是外部類的單例對象。當(dāng)外部類第一次調(diào)用getInstance()方法時才加載內(nèi)部類并創(chuàng)建instance對象,實現(xiàn)了延遲加載。由于instance是靜態(tài)常量,所以只創(chuàng)建一次并且不能被修改。以后調(diào)用getInstance()方法不會再創(chuàng)建instance對象,確保是單例對象。類加載器是在線程同步的環(huán)境下運行的,能夠保證instance對象的創(chuàng)建也是線程同步的[5]。

    2.5 枚舉式

    如示例代碼5所示。

    示例代碼5:

    public enum SingletonClass{

    //定義一個枚舉元素,表示單例對象

    INSTANCE;

    //定義枚舉的其他方法

    public void operation(){

    ……………..} }

    枚舉是JDK1.5引入的新特性,由Java虛擬機保證枚舉本身就是單例模式,也是線程安全的。枚舉元素INSTANCE就是這個枚舉類型的唯一對象,其中可以添加其他的方法供INSTANCE調(diào)用。枚舉方式實現(xiàn)單例具有實現(xiàn)簡單、代碼量最少、線程安全等特點,但無法保證延遲加載[6]。

    2.6 屏蔽反序列化與克隆

    在Java中創(chuàng)建對象的方式有四種,分別是通過new創(chuàng)建對象、反射機制、反序列化和克隆。餓漢式、懶漢式、雙重驗證式和靜態(tài)內(nèi)部類方式都屏蔽了通過new和反射形式創(chuàng)建單例模式對象,但在序列化和克隆要求的特殊情況下,無法做到屏蔽通過反序列化和克隆方式來創(chuàng)建單例模式對象。假定單例模式對象需要實現(xiàn)序列化和克隆功能,示例代碼1、示例代碼2、示例代碼3和示例代碼4必須增加readResolve()和覆蓋clone()方法,以示例代碼2為例進行修改,如示例代碼6所示。

    示例代碼6

    public class SingletonClass implements Serializable{

    private static SingletonClass instance=null;

    private SingletonClass(){}

    public static synchronized SingletonClass getInstance(){

    if(instance==null){

    instance=new SingletonClass();

    }

    return instance;

    }

    //自定義反序列化返回的對象

    private Object readResolve() throws ObjectStreamException{

    return getInstance();

    }

    //執(zhí)行克隆方法時返回的對象

    protected Object clone() throws CloneNotSupportedException{

    return getInstance();

    }}

    在readResolve()和clone()方法中調(diào)用getInstance()返回唯一的單例對象,這樣就避免了在單例模式實現(xiàn)序列化和克隆功能的情況下是一個真正的單例對象。枚舉類型在反序列化和克隆操作時生成的對象還是自己,所以無需考慮序列化和克隆問題。

    2.7 單例模式各實現(xiàn)方式對比

    從表1可以看出,單例模式的五種實現(xiàn)方式都是線程是安全的。調(diào)用效率方面,懶漢式和雙重驗證式都要進行同步,所以要低于餓漢式、靜態(tài)內(nèi)部類和枚舉方式;延遲加載方面,懶漢式、雙重驗證式和靜態(tài)內(nèi)部類式在調(diào)用getInstance()方法時才創(chuàng)建單例對象,支持延遲加載;餓漢式和枚舉式都是在字節(jié)碼加載時創(chuàng)建單例對象,不支持延遲加載。 在序列化和克隆情景下,枚舉式無需添加額外邏輯來保證單例的純粹性;而其余四種方式需要添加readResolve()方法和重寫clone()方法來保證反序列化和克隆操作所得到的結(jié)果仍然是當(dāng)前單例對象。

    表1 單例模式各實現(xiàn)方式比較

    3 單例模式在JDBC中的應(yīng)用

    JDBC是Java語言用來訪問關(guān)系型數(shù)據(jù)庫的一組API,具有使用成本低、執(zhí)行速度快、不依賴于業(yè)務(wù)容器等優(yōu)點,通常在Java EE分層模型中作為持久層的解決方案[7]。JDBC操作過程一般包括4個步驟:①加載數(shù)據(jù)庫驅(qū)動;②創(chuàng)建數(shù)據(jù)庫連接對象Connection;③通過創(chuàng)建Statement對象執(zhí)行SQL語句;④釋放資源。持久層通常采用DAO模式向上層調(diào)用者屏蔽訪問數(shù)據(jù)庫的細節(jié),在DAO接口中定義實體類的持久化方法,在DAO實現(xiàn)類封裝JDBC操作數(shù)據(jù)庫。假如DAO實現(xiàn)類中的每個持久化操作都按照上述步驟編碼,就會存在驅(qū)動類重復(fù)加載、代碼冗余度高、復(fù)用率低等缺點。由于操作①②④與實體對象以及持久化邏輯沒有太多聯(lián)系,所以可通過單例模式封裝成一個工具類,如圖2所示,確保數(shù)據(jù)庫驅(qū)動只加載一次,同時作為數(shù)據(jù)庫訪問的唯一入口。在實體對象的DAO實現(xiàn)中引用這個工具類來執(zhí)行數(shù)據(jù)庫操作,DAO中只關(guān)注步驟③的操作即可,從而降低代碼的冗余度并提高復(fù)用率。

    4 結(jié)論

    單例設(shè)計模式保證單例類只能生成一個實例對象,對于系統(tǒng)中管理資源的類、通過線程同步控制并發(fā)操作的類而言用單例模式封裝能夠保證對資源的合理控制和引用。如果單例對象占用資源少、實現(xiàn)簡單、不考慮序列化和克隆場景并且不需要延遲加載時,則優(yōu)先使用枚舉式。如果單例對象占用資源大、需要延遲加載并且在序列化和克隆場景中使用,則優(yōu)先使用靜態(tài)內(nèi)部類式。如果在多線程環(huán)境中,盡量不要使用懶漢式和雙重驗證式。

    圖2 JDBC數(shù)據(jù)庫訪問工具類

    [1] 陳烽,陳蓉,王跟成,孫懿.設(shè)計模式在區(qū)域綜合管網(wǎng)中的應(yīng)用研究[J].計算機技術(shù)與發(fā)展,2015,25(4):193-196.

    [2] 劉偉.設(shè)計模式[M].北京:清華大學(xué)出版社,2011:92-103.

    [3] 歐陽宏基,葛萌,趙薔.基于JDBC與設(shè)計模式的數(shù)據(jù)庫連接池實現(xiàn)方法[J].計算機技術(shù)與發(fā)展,2011,21(1):84-87.

    [4] 夏浩波.單例模式的設(shè)計與應(yīng)用[J].電腦開發(fā)與應(yīng)用,2011,24(1):58-59.

    [5] 張磊杰,劉永久,王 慧.基于虛擬現(xiàn)實的步態(tài)訓(xùn)練康復(fù)機器人系統(tǒng)軟件設(shè)計[J].計算機系統(tǒng)應(yīng)用,2012,21(12):8-11.

    [6] 陳天超.單例設(shè)計模式研究[J].福建電腦,2016,(8):14-16.

    [7] 歐陽宏基,葛萌,陳偉.基于JDBC的數(shù)據(jù)持久化層性能優(yōu)化研究[J].網(wǎng)絡(luò)新媒體技術(shù),2016,5(5):9-15.

    ResearchandImplementationofSingletonDesignPattern

    Ge Meng, Ouyang Hongji, Chen Wei
    (Computer College, Xianyang Normal University, XianYang 712000, China)

    A

    )

    葛萌(1980-),女,講師,碩士,研究方向為軟件工程. 歐陽宏基(1982-),男,講師,碩士,研究方向為Java EE應(yīng)用,軟件工程. 陳偉(1976-),男,講師,碩士,研究方向為網(wǎng)絡(luò)安全.

    1007-757X(2017)09-0068-03

    猜你喜歡
    枚舉序列化設(shè)計模式
    仿生設(shè)計模式的創(chuàng)新應(yīng)用探索
    玩具世界(2023年6期)2024-01-29 12:14:36
    “1+1”作業(yè)設(shè)計模式的實踐探索
    基于理解性教學(xué)的信息技術(shù)教學(xué)案例研究
    速讀·上旬(2022年2期)2022-04-10 16:42:14
    一種高效的概率圖上Top-K極大團枚舉算法
    如何建構(gòu)序列化閱讀教學(xué)
    甘肅教育(2020年14期)2020-09-11 07:58:36
    交通機電工程設(shè)計模式創(chuàng)新探討
    Java 反序列化漏洞研究
    基于太陽影子定位枚舉法模型的研究
    作文訓(xùn)練微格化、序列化初探
    語文知識(2015年12期)2015-02-28 22:02:15
    互動式設(shè)計模式研究
    宣城市| 日喀则市| 蒲江县| 嘉兴市| 青铜峡市| 合山市| 伊宁市| 海伦市| 乌鲁木齐市| 上蔡县| 独山县| 赣榆县| 深泽县| 黔西县| 山东省| 延边| 日照市| 航空| 寿光市| 甘洛县| 含山县| 逊克县| 越西县| 洮南市| 清涧县| 汤阴县| 苍山县| 济南市| 永善县| 那曲县| 白沙| 江油市| 涞源县| 宜兴市| 聂荣县| 甘谷县| 漳州市| 城市| 永康市| 南安市| 宁安市|