天天看點

教你借助設計模式限制執行個體化數量 | 帶你學《Java面向對象程式設計》之七十三

上一篇:帶你領略類圖以外的世界 | 帶你學《Java面向對象程式設計》之七十二

【本節目标】

通過閱讀本節内容,你将進一步利用所學知識來一步步實作某些開發要求,了解到單例模式與多例模式的實作原理與作用。

單例設計模式(多例設計模式)主要是一種控制執行個體化對象産生個數的設計操作。

單例設計

如果說有一個程式類,假設該程式類的定義如下:

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面向對象程式設計文章檢視此處