【本節目标】
通過閱讀本節内容,你将進一步利用所學知識來一步步實作某些開發要求,了解到單例模式與多例模式的實作原理與作用。
單例設計模式(多例設計模式)主要是一種控制執行個體化對象産生個數的設計操作。
單例設計
如果說有一個程式類,假設該程式類的定義如下:
class Singleton {
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instanceA = new Singleton() ;
Singleton instanceB = new Singleton() ;
Singleton instanceC = new Singleton() ;
instanceA.print() ;
instanceB.print() ;
instanceC.print() ;
}
}
但是由于某些要求,現在要求Singleton這個類隻允許提供有一個執行個體化對象。那麼此時首先控制構造方法因為所有的新的執行個體華對象産生了,那麼一定要調用我們的構造方法,如果“沒有”構造方法,那麼就自然無法産生執行個體化對象了。
範例:構造方法私有化
class Singleton {
private Singleton() {} //構造方法私有化
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
instance = new Singleton() ; //錯誤:Singleton()可以在Singleton中通路private
}
}
但是現在是有嚴格要求的:必須産生有一個執行個體化對象。是以現在需要考慮去産生一個執行個體化對象交給用戶端去調用。那麼這個時候的分析如下:
1、private通路權限的主要特點在于:不能在類外部通路,但是可以在類本身調用,是以現在可以考慮在類的内部調用構造;
class Singleton {
private Singleton instance = new Singleton() ;
private Singleton() {} //構造方法私有化
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
//instance = new Singleton() ; //錯誤:Singleton()可以在Singleton中通路private
}
}
2、此時Singleton類内部的instance屬于一個普通屬性,而普通屬性是在有執行個體化對象産生之後才會被調用的,那麼這個時候外部無法産生執行個體化對象,是以這個屬性就不能通路到了,那麼就必須要考慮如何在沒有執行個體化對象的時候擷取此屬性,那麼隻有一個static屬性可以通路。
class Singleton {
static Singleton instance = new Singleton() ;
private Singleton() {} //構造方法私有化
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
instance = Singleton.instance ;
instance.print() ; //www.mldn.cn
}
}
3、類中的屬性應該封裝後使用,是以理論上此時的instance需要被封裝起來,那麼就需要通過static方法獲得。
class Singleton {
private static Singleton instance = new Singleton() ;
private Singleton() {} //構造方法私有化
public static Singleton getInstance() {
return instance ;
}
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
instance = Singleton.getInstance() ;
instance.print() ; //www.mldn.cn
}
}
4、整個代碼從頭強調的是隻有一個執行個體化對象,但是這個對象依然可以被重新使用。是以需要保證此時Singleton類内部的instance無法再次執行個體化,那麼應該使用final定義。
class Singleton {
private static final Singleton INSTANCE = new Singleton() ;
private Singleton() {} //構造方法私有化
public static Singleton getInstance() {
return INSTANCE ;
}
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
instance = Singleton.getInstance() ;
instance.print() ; //www.mldn.cn
}
}
在很多情況下有些類是不需要重複産生對象的,例如:如果一個程式啟動,那麼現在肯定需要有一個類負責儲存有一些程式加載的資料資訊。
圖一 單例設計
對于單例設計模式也分為兩種:懶漢式、餓漢式。在之前所定義的都屬于餓漢式。在系統加載類的時候就會自動提供Singleton類的執行個體化,而懶漢式是在第一次使用的時候進行執行個體化對象處理。
範例:将單例修改為懶漢式
class Singleton {
private static Singleton instance ;
private Singleton() {} //構造方法私有化
public static Singleton getInstance() {
if(instance == null) { //第一次使用
instance = new Singleton() ; //執行個體化對象
}
return instance ;
}
public void print() {
System.out.println("www.mldn.cn") ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Singleton instance = null ; //聲明對象
instance = Singleton.getInstance() ;
instance.print() ; //www.mldn.cn
}
}
面試題:請編寫一個Singleton程式,并說明其主要特點?
- 代碼如上,可以把懶漢式(後面需要考慮到線程同步問題)和餓漢式都寫上;
- 特點:構造方法私有化,類内部提供static方法擷取執行個體化對象,這樣不管外部如何操作,永遠都隻有一個執行個體化對象提供。
多例設計
與單例設計對應的還有一個多例設計,單例設計指的是隻保留有一個執行個體化對象,而多例設計指的是可以保留有多個執行個體化對象。例如:如果現在定義一個描述性别的類。那麼該對象隻有兩個:男、女。或者描述顔色基色的類,可以使用紅色、綠色、藍色。這種情況下就可以使用多例設計來解決。
範例:實作多例設計
class Color { //定義描述顔色的類
private static final Color RED= new Color("紅色") ;
private static final Color GREEN= new Color("綠色") ;
private static final Color BLUE= new Color("藍色") ;
private String title;
private Color(String title) { //構造方法私有化
this.title = title ;
}
public static Color getInstance(String color) {
switch(color) {
case "red": return RED ;
case "green": return GREEN ;
case "blue": return BLUE ;
default: return null ;
}
}
public String toString() {
return this.title ;
}
}
public class JavaDemo{
public static void main(String args[]) {
Color c =Color.getInstance("green") ;
System.out.println(c) ;
} //綠色
}
多例設計與單例設計的本質是相同的,一定都會在内部提供有static方法以傳回執行個體化對象。
想學習更多的Java的課程嗎?從小白到大神,從入門到精通,更多精彩不容錯過!免費為您提供更多的學習資源。
本内容視訊來源于
阿裡雲大學 下一篇:迅速了解多例模式競争者-枚舉 | 帶你學《Java面向對象程式設計》之七十四 更多Java面向對象程式設計文章檢視此處