999精品在线视频,手机成人午夜在线视频,久久不卡国产精品无码,中日无码在线观看,成人av手机在线观看,日韩精品亚洲一区中文字幕,亚洲av无码人妻,四虎国产在线观看 ?

單例設計模式的研究與實現

2017-10-12 03:23:08葛萌歐陽宏基陳偉咸陽師范學院計算機學院陜西咸陽712000
微型電腦應用 2017年9期

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

單例設計模式的研究與實現

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

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

單例模式; 設計模式; 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 引言

在利用面向對象技術進行應用系統開發中合理使用設計模式,能夠獲得靈活的應用架構、良好的擴展性和較高的復用率。設計模式是一組精心設計的類和接口的組合,包含若干角色,每個類或接口充當一種角色承擔一個職責。設計模式通常在某個應用場景下使用,它

為某種重復出現的問題提供一種最佳的指導方針和解決方案。GOF等人總結了軟件開發中使用頻率最高的23種設計模式,并根據模式的目的將它們分為三類:創建型、結構型和行為型。創建型模式主要用于創建對象;結構型模式用于處理類或對象的組合;行為型模式主要用于描述類或對象如何交互并分配責任。每個模式都包含四個關鍵的要素:模式名稱、問題、解決方案和效果[1]。

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

1 單例設計模式分析

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

圖1 單例模式結構圖

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

2 單例模式的實現方式

2.1 餓漢式

如示例代碼1所示:

示例代碼1

public class SingletonClass {

private static final SingletonClass instance=new SingletonClass();

private SingletonClass (){}

public static SingletonClass getInstance(){

return instance;}}

從示例代碼1可以看出,該類中有一個靜態成員instance,該成員在類加載時就被創建生成實例對象,final關鍵字確保該對象不被自身所修改。唯一的構造方法是私有訪問權限,確保了外部類無法創建SingletonClass的對象;同時該構造方法對子類不可見,也就保證不能通過繼承的方式來創建SingletonClass的對象。獲取唯一實例的方式是調用靜態getInstance()方法。由于這個唯一的對象是在類加載的時候創建,因此稱為餓漢式。由于類加載器是線程安全的,所以生成的單例對象也是線程安全的,但此方式不能做到對單例對象的延遲加載。延遲加載是節省內存的一種有效手段,強調在使用某個對象的時候再創建該對象,避免提前創建而長時間又不使用該對象的情況[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可以看出,在類加載時并不創建單例對象,而是在調用getInstance()方法時判斷單例對象是否存在,如果不存在再創建并返回該對象的引用。由于將單例對象的創建延遲到使用時才創建,所以稱為懶漢式。考慮到多線程環境下的線程同步問題,在靜態方法getInstance()前加入synchronized 關鍵字,確保多線程環境下單例對象只創建一次。懶漢式做到了延遲加載,但每次在調用getInstance()方法時都需要線程同步,調用效率較低。

2.3 雙重驗證式

如示例代碼3所示:

示例代碼3

public class SingletonClass{

private static SingletonClass instance=null;

private SingletonClass(){}

public static SingletonClass getInstance(){

//第一次判斷單例對象是否已經存在

if(instance==null){

synchronized(SingletonClass.class)

{

//第二次判斷單例對象是否已經存在

if(instance==null){

instance=new SingletonClass();

} }

return instance;

}}

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

2.4 靜態內部類式

如示例代碼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中定義了一個私有的靜態內部類SingletonClassHolder,其中的instance就是外部類的單例對象。當外部類第一次調用getInstance()方法時才加載內部類并創建instance對象,實現了延遲加載。由于instance是靜態常量,所以只創建一次并且不能被修改。以后調用getInstance()方法不會再創建instance對象,確保是單例對象。類加載器是在線程同步的環境下運行的,能夠保證instance對象的創建也是線程同步的[5]。

2.5 枚舉式

如示例代碼5所示。

示例代碼5:

public enum SingletonClass{

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

INSTANCE;

//定義枚舉的其他方法

public void operation(){

……………..} }

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

2.6 屏蔽反序列化與克隆

在Java中創建對象的方式有四種,分別是通過new創建對象、反射機制、反序列化和克隆。餓漢式、懶漢式、雙重驗證式和靜態內部類方式都屏蔽了通過new和反射形式創建單例模式對象,但在序列化和克隆要求的特殊情況下,無法做到屏蔽通過反序列化和克隆方式來創建單例模式對象。假定單例模式對象需要實現序列化和克隆功能,示例代碼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();

}

//執行克隆方法時返回的對象

protected Object clone() throws CloneNotSupportedException{

return getInstance();

}}

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

2.7 單例模式各實現方式對比

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

表1 單例模式各實現方式比較

3 單例模式在JDBC中的應用

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

4 結論

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

圖2 JDBC數據庫訪問工具類

[1] 陳烽,陳蓉,王跟成,孫懿.設計模式在區域綜合管網中的應用研究[J].計算機技術與發展,2015,25(4):193-196.

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

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

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

[5] 張磊杰,劉永久,王 慧.基于虛擬現實的步態訓練康復機器人系統軟件設計[J].計算機系統應用,2012,21(12):8-11.

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

[7] 歐陽宏基,葛萌,陳偉.基于JDBC的數據持久化層性能優化研究[J].網絡新媒體技術,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應用,軟件工程. 陳偉(1976-),男,講師,碩士,研究方向為網絡安全.

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

主站蜘蛛池模板: 久久 午夜福利 张柏芝| 国产精品无码久久久久久| 午夜性爽视频男人的天堂| 国产美女91视频| 亚洲成网777777国产精品| 亚洲欧美日韩中文字幕在线一区| 国产在线观看一区精品| 露脸国产精品自产在线播| 欧美一级在线看| 成人午夜视频网站| 婷婷伊人五月| 国产在线观看99| 2019国产在线| 国产亚洲精久久久久久无码AV| 免费人成视网站在线不卡| 小说 亚洲 无码 精品| 国产欧美在线观看一区| 四虎国产在线观看| 欧美日本在线| 亚洲激情99| 精品视频91| v天堂中文在线| 欧美视频免费一区二区三区| 91毛片网| 国产毛片久久国产| 国内99精品激情视频精品| 亚洲成人网在线播放| 伊人成人在线| 亚洲成肉网| 宅男噜噜噜66国产在线观看| 五月天婷婷网亚洲综合在线| 国产美女91视频| 无码精品国产VA在线观看DVD| 国产不卡在线看| 91www在线观看| 欧美啪啪一区| 在线国产91| 在线观看国产黄色| 亚洲无码A视频在线| 色综合日本| 爱爱影院18禁免费| 18禁黄无遮挡网站| 欧美翘臀一区二区三区| 综合色在线| 人人爽人人爽人人片| 国精品91人妻无码一区二区三区| 日韩免费毛片| jizz国产视频| 国产综合精品一区二区| 欧美日韩国产综合视频在线观看| 伊人91视频| 成人av专区精品无码国产| 日韩无码视频专区| 中文字幕在线永久在线视频2020| 免费观看国产小粉嫩喷水| 亚洲免费播放| 婷婷激情亚洲| 五月天综合网亚洲综合天堂网| vvvv98国产成人综合青青| 中文精品久久久久国产网址| 日韩AV手机在线观看蜜芽| 国模私拍一区二区三区| 人妻21p大胆| 亚洲看片网| 国产一区成人| 亚洲成aⅴ人在线观看| 欧美成人午夜影院| 久久亚洲综合伊人| 99这里只有精品在线| 日本色综合网| 亚洲欧美国产五月天综合| 国产精品亚洲а∨天堂免下载| 久久精品一品道久久精品| 97人妻精品专区久久久久| 又爽又大又黄a级毛片在线视频| 97人妻精品专区久久久久| 成人精品亚洲| 丝袜无码一区二区三区| 在线日韩一区二区| 四虎影视8848永久精品| 老汉色老汉首页a亚洲| 欧美69视频在线|