2010-03-19 82 views
1

請給我一個單例模式的實時示例。 訪問共享文件的不同線程是單例還是不單?由於每個線程訪問文件的同一個實例,而不是他們自己的個別實例。單例模式示例

回答

1

是的,但只有當所有線程訪問同一個文件,並且您使用的是自定義實現(不java.io.File,也許是一個包裝)

Singleton模式是用來限制實例化設計模式一類以一個對象

單身人士(常常是一個不錯的選擇)的是,可以有在整個程序只有一個實例類。

例如,一個SingletonConfigFile可能看起來像這樣。請記住:

  • 它僅用於讀取一個文件。這是有意義的,這是一個配置文件。
  • 如果你的類可以被多次實例化,對於不同的文件,它不是單例。
  • 不使用此代碼 - 它不考慮併發問題,這是一個完全不同的討論區域。

public SingletonConfigFile { 
    private static String filename = "config.xml"; 
    private File file; 
    private static SingletonConfigFile instance; 

    private SingletonConfigFile() { 
     if (instance != null) { 
      throw new Error(); 
     } 
     file = new File(filename); 
    } 

    public synchronized SingletonConfigFile getInstance() { 
     if (instance == null) { 
      instance = new SignletonConfigFile(); 
     } 
     return instance 
    } 

    public String read() { 
     // delegate to the underlying java.io.File 
    } 
} 

但是這個例子是在感覺的邊緣。在只有一個對象的情況下使用單身(如上所述)。例如,它有意義的有:

  • RingOfPower.getInstance() - 只有一個能量環(索倫的),並且不能存在更多。
  • Sun.getInstance() - 只有一顆恆星叫做「太陽」。
  • 在應用程序中的所有withing對象邏輯上應該只出現一次 - 註冊表,應用程序上下文等
+0

再怎麼樣我上面的文件示例? – JavaUser 2010-03-19 06:32:03

+0

@JavaUser我更新了我的答案,以澄清您的示例 – Bozho 2010-03-19 06:39:16

+0

@downvoter我會感謝您的理由。 – Bozho 2010-03-19 08:40:24

4

A「文件」不是一個Java對象(和java.io.File絕對不是一個單身人士)。我不會將磁盤上的文件看作單例文件 - 它們只是共享資源。特別是,它不像磁盤上只有一個文件:)

單例模式的一個更常見的例子是配置 - 或記錄。例如,LogManager.getLogManager返回「該」LogManager,並且不能創建新的。同樣,你可能有一個可以靜態訪問的公共配置對象。 (在依賴注入系統中,配置可能不是而是是單例,但是每個組件都提供他們需要的配置位,以便它們不必獲取「普通」配置)。

+0

thx ..無論如何日誌不是寫在單獨的文件,他們只寫在同一個文件。所以我認爲它的單身......你的意見是什麼? – JavaUser 2010-03-19 06:39:47

+0

單身漢不是關於文件,而是關於對象。單件對象可以訪問一百個文件,或者根本不需要訪問任何文件 – dbemerlin 2010-03-19 06:57:08

1

單例通常意味着只有一個實例可以存在。

放鬆可能是一個知名的全系統單一實例的類(除了可能創建的其他實例)。

java.io.File不是Singleton類。

1

辛格爾頓是在一個類被賦予了私有的構造和特殊「的getInstance()」,「實例()」,或「實例()」靜態功能,負責返回設計反模式 (並且可能構造,取決於你是否使用懶惰單例)唯一的對象實例。單元經常導致依賴膨脹,同時隱藏依賴關係,並且很難在單元測試期間嘲笑單例類,或者用非單例的單元替換單例,當事實證明對象應該是單例時,實際上持有。

單體反模式的解決方案是使用稱爲「依賴注入」的東西。你可能會發現這個Google Techtalk,標題爲Java on Guice,它解釋了依賴注入,啓發。

還有另外一種單身模式,它與singleton反模式無關......也就是說,如果你碰巧只創建一個類的一個實例並傳遞它,但是你沒有使用靜態構造函數強制單例,然後你有效地創建了一個單獨的類,而不會將自己鎖定到依賴關係中,或者阻止該類以後不是單身的可能性。在我已經指出的Google Techtalk中,發言者在發言結束時提到了這種單身性。

0

在Java J2SE API中 - 兩個類CalendarRuntime是單例模式實時實現的很好例子。

-Arun

+0

您能解釋一下我的原因嗎? – JavaUser 2010-03-19 08:02:38

+1

日曆不是單身人士 – Bozho 2010-03-19 08:48:11

+0

限制對類構造函數的訪問並不會使其成爲Singleton。 Calendar類的構造函數是受保護的,並且該類提供了一個getInstance()方法來獲取該類的一個實例。但是,每次調用getInstance()都會獲得該類的新實例。所以這不是一個* Singleton * – Narayan 2010-03-19 08:52:06

0

最佳實時例子是讀取屬性文件的數據,你只需要一個實例。請找到下面的代碼演示例如

public class SingleTonDesignPattern { 
    public static SingleTonDesignPattern singleTon = null; 
    public Properties priperty = null; 

    private SingleTonDesignPattern() { 

    } 

    public static SingleTonDesignPattern getSingleTon() { 
     return singleTon; 
    } 

    public Properties getPriperty() { 
     return priperty; 
    } 

    public void setPriperty(Properties priperty) { 
     this.priperty = priperty; 
    } 

    public static synchronized SingleTonDesignPattern getSingleTonObject() { 
     if(singleTon == null) { 
      singleTon = new SingleTonDesignPattern(); 
      Properties properties1 = new Properties(); 
      try { 
       properties1.load(new FileInputStream("c:/labels.properties")); 
       singleTon.setPriperty(properties1); 
      } catch (FileNotFoundException ex) { 
       ex.printStackTrace(); 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
     return singleTon; 
    } 

} 
0
public class Singleton { 

    private static Singleton singleton = new Singleton(); 

    /* A private Constructor prevents any other 
    * class from instantiating. 
    */ 
    private Singleton(){ } 

    /* Static 'instance' method */ 
    public static Singleton getInstance() { 
     return singleton; 
    } 
    /* Other methods protected by singleton-ness */ 
    protected static void demoMethod() { 
     System.out.println("demoMethod for singleton"); 
    } 
}