JavaRush /Java Blog /Random-TW /模式和單例 - 適合所有第一次遇到它們的人

模式和單例 - 適合所有第一次遇到它們的人

在 Random-TW 群組發布
本文針對的是那些第一次接觸模式概念、聽說過Singleton'e 或以某種方式製作它,但仍然不理解任何東西的人。歡迎!JavaRush 學生在第 15 級第一次遇到模式,當時上限意外地要求「修復」並使用Singleton惰性實現來實現模式。第一次聽到的同學Singleton立刻就有一堆疑問:什麼是模式,為什麼需要它,它是什麼樣的模式,Singleton最後,這是什麼樣的惰性實現。我們開始按順序回答: 模式和單例 - 對於每個第一次遇到它們的人 - 1

到底什麼是模式?

為了更好地理解,我認為有必要從歷史來回答這個問題。程式設計師中有這樣一位著名的四位作者:Erich Gamma、Richard Helm、Ralph Johnson 和 John Vlissides,他們提出了一個有趣的想法。
模式和單例 - 對於每個第一次遇到它們的人 - 2
他們注意到,在編寫程式時,他們經常必須解決大致相同的問題並編寫結構相同類型的程式碼。因此,他們決定以模式的形式來描述物件導向程式設計中經常使用的典型模式。該書於 1995 年出版,書名為「物件導向設計技術」。設計模式”。結果書名太長,乾脆就叫《四人幫之書》。第一版中發布了 23 種模式,此後又發現了數十種其他模式。因此,在回答本段的問題「什麼是模式?」時,讓我們用幾句話來總結:
模式是常見問題的標準化解決方案。
Singleton只是這些模式之一。

為什麼我們需要模式(設計模式)

您可以在不知道模式的情況下進行編程;您可以通過認識到這樣一個事實來驗證這一點:到JavaRush 的第15 級時,您已經編寫了數百個小程序,但對它們的存在一無所有所知。這表明模式是一種工具,它的存在將大師與業餘愛好者區分開來:
模式和單例 - 適合所有第一次遇到它們的人 - 3
這些模式描述瞭如何正確解決典型問題之一。因此,了解這些模式可以節省您的時間。可以用演算法來類比。例如,您可以提出自己的二十一點和數字排序演算法,並在其上花費大量時間,或者您可以使用很久以前已經描述過的演算法並實現它。模式也是如此。另外,透過使用模式,程式碼變得更加標準化,並且當使用正確的模式時,您將不太可能犯錯,因為在該模式中已經預見並消除了錯誤。嗯,除此之外,模式知識可以讓程式設計師更好地相互理解。只需說出模板的名稱就足夠了,而不是試圖向其他程式設計師解釋您希望他們做什麼。 因此,總而言之,設計模式有助於:
  • 不要重新發明輪子,而是使用標準解決方案;
  • 標準化代碼;
  • 術語標準化;
在本節的結論中,我們注意到所有模式都可以簡化為三大組:
模式和單例 - 對於每個第一次遇到它們的人 - 4

最後是單例模式

Singleton生成模式。它的直譯是孤獨的。這種模式確保一個類別只有一個物件(該類別的一個實例),並且為該物件提供了一個全域存取點。從描述中應該可以清楚看出,該模式應該在兩種情況下使用:
  1. 當您的程式中不應建立任何類別的多個物件時。例如,在一款電腦遊戲中,您有一個「角色」類,而該類別應該只有一個描述角色本身的物件。

  2. 當您需要為類別物件提供全域存取點時。換句話說,您需要確保從程式中的任何位置呼叫該物件。而且,遺憾的是,為此僅創建一個全域變數是不夠的,因為它沒有寫入保護,任何人都可以更改該變數的值,並且該物件的全域存取點將會遺失。Singleton例如,當您有一個與資料庫一起使用的類別的對象,並且您需要可以從程式的不同部分存取資料庫時,就需要這些屬性。並且Singleton它將保證沒有其他代碼替換了先前創建的類別的實例。
解決這兩個問題的方法是Singleton:程式中必須只有一個對象,並且必須可以全域存取它。在第 15 級的範例中,上限要求為以下任務實現此模式(以下是其描述):
模式和單例 - 對於每個第一次遇到它們的人 - 5
仔細閱讀條件後,就清楚為什麼Singleton這裡需要 (Single) 了。畢竟,程式要求您為每個類別建立一個物件:Sun, Moon, Earth。假設程式中的每個類別不應創建超過一個太陽/月亮/地球,這是合乎邏輯的,否則這將是荒謬的,除非您正在編寫自己的星際大戰版本。 三步驟Java實現Singleton的特點 Java中的單一例行化為不能使用常規的建構子來實現,因為建構子總是會傳回一個新物件。因此,Singleton'a 的所有實作都歸結為隱藏建構函式並建立一個公共靜態方法,該方法將控制單一物件的存在並「銷毀」所有新出現的物件。如果Singleton呼叫 'a,它必須建立一個新物件(如果程式中尚不存在)或傳回已建立的物件。為此: #1。– 您需要為包含單一物件的類別新增私人靜態欄位:
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance; //#1
}
#2. – 將類別建構函式(預設建構函式)設為私有(以便在類別外部關閉對其的訪問,然後它將無法傳回新物件):
public class LazyInitializedSingleton {
	private static LazyInitializedSingleton instance;
private LazyInitializedSingleton(){} // #2
}
#3 . – 宣告一個靜態建立方法,用於取得單例:
public class LazyInitializedSingleton {
    private static LazyInitializedSingleton instance;
        private LazyInitializedSingleton(){}
        public static LazyInitializedSingleton getInstance(){ // #3
        if(instance == null){		//if the object has not been created yet
            instance = new LazyInitializedSingleton();	//create a new object
        }
        return instance;		// return the previously created object
    }
}
上面的例子有點笨拙,因為我們只是隱藏了構造函數並提供了我們自己的方法而不是標準構造函數。由於本文旨在讓 JavaRush 學生第一次接觸這種模式(以及一般模式),因此這裡不會給出更複雜的 Singleton 的實作特性。我們僅注意到,根據程序的複雜性,可能需要對此模式進行更詳細的細化。例如,在多執行緒環境中(請參閱執行緒主題),多個不同的執行緒可以同時呼叫 Singleton 的 getter 方法,而上述程式碼將停止運作,因為每個單獨的執行緒將能夠建立該類別的多個實例立刻。因此,仍然有幾種不同的方法來建立正確的線程安全單例。但這是另一個故事了 =) 最後。cap 要求的延遲初始化是什麼 ? 延遲初始化也稱為延遲初始化。這是一種程式設計技術,其中資源密集型操作(創建物件是資源密集型操作)是按需執行的,而不是提前執行的。這基本上就是我們的程式碼Singleton'a. 換句話說,我們的物件是在訪問時創建的,而不是提前創建的。不應假設延遲初始化的概念在某種程度上與Singleton'om. 延遲初始化也用於其他生成設計模式,例如代理和工廠方法,但那是另一個故事了 =) 在準備本文時使用了以下來源:
  1. Java 單例設計模式最佳實務與範例
  2. 設計模式
  3. Java 中正確的單例
留言
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION