Java設計模式理論知識即單例設計模式
程式:1.可維護性、2.可複用性、3.可擴充套件性、4.靈活性好 ;通過封裝、繼承、多型把程式的耦合度降低 開放-封閉原則(設計總原則) 開閉原則就是說對擴充套件開放,對修改關閉。在程式需要進行拓展的時候,不能去修改原有的程式碼,而是要擴充套件原有程式碼,實現一個熱插拔的效果。所以一句話概括就是:為了使程式的擴充套件性好,易於維護和升級。想要達到這樣的效果,我們需要使用介面和抽象類等 單一職責原則 就一個類而言,應該僅有一個引起它變化的原因(如果你能夠想到多於一個的動機去改變一個類,那麼這個類就具有多一個的職責,就應該考慮類的職責分離) 依賴倒轉原則 抽象不應該依賴細節,細節應該依賴於抽象;高層模組不應該依賴低層模組。兩個都應該依賴抽象 里氏代換原則
單例模式(singleton)—單執行緒
保證一個類僅有一個例項,並提供一個訪問它的全域性訪問點,避免一個全域性使用的類頻繁的建立和銷燬,節省系統資源,提高程式效率。Java是這麼建立例項的 Person p = new Person();但是這麼建立會建立多個例項,所以我們必須把構造器(構造方法)設為私有(private),這樣其他類就不能使用new來例項化一個類。所有類都有構造方法,不編碼則系統預設生成空的構造方法,若有顯示定義的構造方法,則預設的構造方法就會失效。 “通常我們可以讓一個全域性變數使得一個物件被訪問,但他不能防止你例項化多個物件。一個最好的辦法就是,讓類自身負責儲存它的唯一例項。這個可以保證沒有其它例項可以被建立,並且它可以提供一個訪問該例項的方法。”
package singleton;
public class Singleton {
//定義一個屬性,用來儲存Singleton類物件的例項
private static Singleton instance;
//構造方法讓其private,這樣就可以堵死外界利用new建立此類例項的可能
private Singleton() {
}
//此方法是獲得本類例項的唯一全域性訪問點
public static Singleton GetInstance() {
//若例項不存在,則new一個新例項,否則返回已有的例項
if (instance == null) {
instance = new Singleton();
}
return instance; //若例項存在,直接返回例項物件
}
}
客戶端程式碼
package singleton;
import java.io.Console;
public class Main {
public static void main(String[] args) {
Singleton s1 = Singleton.GetInstance();
Singleton s2 = Singleton.GetInstance();
//比較兩次例項化後物件的結果是例項相同
System.out.println(s1 == s2); //結果為true---->表示為同一個例項物件
}
}
這種實現方式並不是執行緒安全的,當有多個執行緒同時呼叫Singleton.getInstance()方法時會產生多個例項。需要通過改造,在多線下如何實現單例模式。可以給程序一把鎖來處理,確保當一個執行緒位於程式碼的臨界區時,另一個執行緒不進入臨界區。如果其他執行緒檢視進入鎖定的程式碼,則它將一直等待(即被阻止),直到該物件被釋放。
package singleton;
public class Singleton {
//定義一個屬性,用來儲存Singleton類物件的例項
private static Singleton instance;
//構造方法讓其private,這樣就可以堵死外界利用new建立此類例項的可能
private Singleton() {
}
//此方法是獲得本類例項的唯一全域性訪問點
public static Singleton GetInstance() {
//先判斷實力是否存在,不存在再加鎖處理
//synchronized加鎖同步會降低效率,這裡先判斷是否為空
//不為空則不需要加鎖,提高程式效率
if (instance == null) {
synchronized (Singleton.class) {
if (instance == null) {
instance = new Singleton();
}
}
}
return instance; //若例項存在,直接返回例項物件
}
}
現在這樣,我們不用讓執行緒每次都加鎖,而只是在例項未被建立的時候再加鎖處理。同時也能保證多執行緒的安全。這種做法被稱為雙重鎖定。
package cn.smbms.tools;
public class Singleton {
private static Singleton singleton;
private Singleton(){
//在整個應用執行期間,只執行一次的業務程式碼操作(比如:讀取配置檔案的操作)
}
public static class SingletonHelper{
private static final Singleton INSTANCE = new Singleton();
}
public static Singleton getInstance(){
return SingletonHelper.INSTANCE;
}
public static Singleton test(){
return singleton;
}
}
客戶端程式碼
package cn.smbms.tools;
public class TestSingleton {
public static void main(String[] args) {
System.out.println("Singleton.test()-----> "
+ Singleton.test());
System.out.println("Singleton.getInstance()-----> "
+ Singleton.getInstance());
}
}
測試結果 在靜態初始化的方式是在自己被載入時就將自己例項化,所以被形象的稱之為餓漢式單例類(缺點是,會提前佔用系統資源)。而在第一次被引用時,才會將自己例項化,被稱之為懶漢式單例類(缺點是,面臨多執行緒訪問的安全性問題,及非執行緒安全模式類)。 單例模式優點 1 在記憶體中只有一個物件,節省記憶體空間。 2 避免頻繁的建立銷燬物件,可以提高效能。 3 避免對共享資源的多重佔用。 4 可以全域性訪問。 適用場景 1 需要頻繁例項化然後銷燬的物件。 2 建立物件時耗時過多或者耗資源過多,但又經常用到的物件。 3 有狀態的工具類物件。 4 頻繁訪問資料庫或檔案的物件。 5 以及其他所有要求只有一個物件的場景。