国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 學(xué)院 > 開發(fā)設(shè)計 > 正文

Java模式設(shè)計之單例模式(二)

2019-11-18 15:41:02
字體:
供稿:網(wǎng)友

  在什么情況下使用單例模式

  使用單例模式的條件

  使用單例模式有一個很重要的必要條件:

  在一個系統(tǒng)要求一個類只有一個實例時才應(yīng)當(dāng)使用單例模式。反過來說,假如一個類可以有幾個實例共存,那么就沒有必要使用單例類。但是有經(jīng)驗的讀者可能會看到很多不當(dāng)?shù)厥褂脝卫J降睦?,可見做到上面這一點并不輕易,下面就是一些這樣的情況。

  例子一

  問:我的一個系統(tǒng)需要一些"全程"變量。學(xué)習(xí)了單例模式后,我發(fā)現(xiàn)可以使用一個單例類盛放所有的"全程"變量。請問這樣做對嗎?
 
  答:這樣做是違反單例模式的用意的。單例模式只應(yīng)當(dāng)在有真正的"單一實例"的需求時才可使用。

  一個設(shè)計得當(dāng)?shù)南到y(tǒng)不應(yīng)當(dāng)有所謂的"全程"變量,這些變量應(yīng)當(dāng)放到它們所描述的實體所對應(yīng)的類中去。將這些變量從它們所描述的實體類中抽出來, 放到一個不相干的單例類中去,會使得這些變量產(chǎn)生錯誤的依靠關(guān)系和耦合關(guān)系。

  例子二

  問:我的一個系統(tǒng)需要治理與數(shù)據(jù)庫的連接。學(xué)習(xí)了單例模式后,我發(fā)現(xiàn)可以使用一個單例類包裝一個Connection 對象,并在finalize()方法中關(guān)閉這個Connection 對象。這樣的話,在這個單例類的實例沒有被人引用時,這個finalize() 對象就會被調(diào)用,因此,Connection 對象就會被釋放。這多妙啊。

  答:這樣做是不恰當(dāng)?shù)?。除非有單一實例的需求,不然不要使用單例模式。在這里Connection 對象可以同時有幾個實例共存,不需要是單一實例。

  單例模式有很多的錯誤使用案例都與此例子相似,它們都是試圖使用單例模式治理共享資源的生命周期,這是不恰當(dāng)?shù)摹? 單例類的狀態(tài)

  有狀態(tài)的單例類

  一個單例類可以是有狀態(tài)的(stateful),一個有狀態(tài)的單例對象一般也是可變(mutable) 單例對象。
有狀態(tài)的可變的單例對象經(jīng)常當(dāng)做狀態(tài)庫(repositary)使用。比如一個單例對象可以持有一個int 類型的屬性,用來給一個系統(tǒng)提供一個數(shù)值惟一的序列號碼,作為某個販賣系統(tǒng)的賬單號碼。當(dāng)然,一個單例類可以持有一個聚集,從而答應(yīng)存儲多個狀態(tài)。

  沒有狀態(tài)的單例類

  另一方面,單例類也可以是沒有狀態(tài)的(stateless), 僅用做提供工具性函數(shù)的對象。既然是為了提供工具性函數(shù),也就沒有必要創(chuàng)建多個實例,因此使用單例模式很合適。一個沒有狀態(tài)的單例類也就是不變(Immutable) 單例類; 關(guān)于不變模式,讀者可以參見本書的"不變(Immutable )模式"一章。

  多個JVM 系統(tǒng)的分散式系統(tǒng)

  EJB 容器有能力將一個EJB 的實例跨過幾個JVM 調(diào)用。由于單例對象不是EJB,因此,單例類局限于某一個JVM 中。換言之,假如EJB 在跨過JVM 后仍然需要引用同一個單例類的話,這個單例類就會在數(shù)個JVM 中被實例化,造成多個單例對象的實例出現(xiàn)。一個J2EE應(yīng)用系統(tǒng)可能分布在數(shù)個JVM 中,這時候不一定需要EJB 就能造成多個單例類的實例出現(xiàn)在不同JVM 中的情況。

  假如這個單例類是沒有狀態(tài)的,那么就沒有問題。因為沒有狀態(tài)的對象是沒有區(qū)別的。但是假如這個單例類是有狀態(tài)的, 那么問題就來了。舉例來說,假如一個單例對象可以持有一個int 類型的屬性,用來給一個系統(tǒng)提供一個數(shù)值惟一的序列號碼,作為某個販賣系統(tǒng)的賬單號碼的話,用戶會看到同一個號碼出現(xiàn)好幾次。
在任何使用了EJB、RMI 和JINI 技術(shù)的分散式系統(tǒng)中,應(yīng)當(dāng)避免使用有狀態(tài)的單例模式。

  多個類加載器

  同一個JVM 中會有多個類加載器,當(dāng)兩個類加載器同時加載同一個類時,會出現(xiàn)兩個實例。在很多J2EE 服務(wù)器答應(yīng)同一個服務(wù)器內(nèi)有幾個Servlet 引擎時,每一個引擎都有獨立的類加載器,經(jīng)有不同的類加載器加載的對象之間是絕緣的。

  比如一個J2EE 系統(tǒng)所在的J2EE 服務(wù)器中有兩個Servlet 引擎:一個作為內(nèi)網(wǎng)給公司的網(wǎng)站治理人員使用;另一個給公司的外部客戶使用。兩者共享同一個數(shù)據(jù)庫,兩個系統(tǒng)都需要調(diào)用同一個單例類。假如這個單例類是有狀態(tài)的單例類的話,那么內(nèi)網(wǎng)和外網(wǎng)用戶看到的單例對象的狀態(tài)就會不同。除非系統(tǒng)有協(xié)調(diào)機(jī)制,不然在這種情況下應(yīng)當(dāng)盡量避免使用有狀態(tài)的單例類。

發(fā)表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發(fā)表
主站蜘蛛池模板: 梁山县| 鄂温| 邹平县| 和田县| 凉城县| 广南县| 龙南县| 沾益县| 南雄市| 本溪| 上饶市| 宁安市| 云霄县| 鲁山县| 延长县| 富宁县| 奉化市| 无极县| 沭阳县| 安远县| 渭南市| 辉南县| 晋宁县| 阳曲县| 会宁县| 页游| 西林县| 广安市| 子洲县| 泾川县| 贵州省| 东丽区| 榆中县| 中方县| 于都县| 青神县| 福海县| 富顺县| 东莞市| 安泽县| 卢湾区|