創建型設計模式-單例模式
軟件設計模式(Design pattern),又稱設計模式,是一套被反覆使用、多數人知曉的、經過分類編目的、代碼設計經驗的總結。使用設計模式是爲了可重用代碼、讓代碼更容易被他人理解、保證代碼可靠性、程序的重用性。
在介紹設計模式的前提下我覺得對基於設計模式的六大原則應該有所瞭解:
1、開閉原則(open close Principle)
在面向對象的編程領域當中,開閉原則規定儘量做到"軟件中的對象(類、模塊、函數等等)應該對於擴展是開放的,但是對於修改是封閉的"這意味着一個實體是允許不改變它的源碼的前提下變更它的行爲。該特性在 產品化的環境中是特別有價值的,在這種環境中,改變源代碼需要代碼審覈,單元測試以及諸如此類的用以確保產品使用質量的過程。遵循這種原則的代碼在擴展時並不發生改變,因此無需上述的過程。
2、里氏代換原則(Liskov Substitution Principle LSP)
- 單例模式
// 餓漢模式
package singlemodel;
/**
* 餓漢式
* @Auther: ZQB
* Date:2020/1/19
*/
public class Singleton1 {
private static Singleton1 instace = new Singleton1();
private Singleton1(){}
//類加載線程安全,方法沒有同步調用效率高。
public static Singleton1 getInstance(){
return instace;
}
}
//懶漢模式
package singlemodel;
/**
* 懶漢式
* @Auther: ZQB
* Date:2020/1/19
*/
/**
* 懶漢式模式
* @Auther: ZQB
* Date:2020/1/19
*/
public class Singleton2 {
private static Singleton2 instance;
private Singleton2(){}
//線程不安全需要添加synchronized同步塊,調用效率低
public static synchronized Singleton2 getInstance(){
if (instance == null){
instance=new Singleton2();
}
return instance;
}
}
// 靜態內部類的方式加載
package singlemodel;
/**
* 靜態內部類
* @Auther: ZQB
* Date:2020/1/19
*/
public class Singleton4 {
//當進行類初始化的時候,不會初始其靜態內部類,實現了延時加載
private static class SingletonClassInstance{
private static final Singleton4 instance = new Singleton4();
}
public static Singleton4 getInstance(){
return SingletonClassInstance.instance;
}
private Singleton4(){}
}
// 雙重檢測鎖模式
package singlemodel;
/**
* 雙重檢測鎖模式
* @Auther: ZQB
* Date:2020/1/19
*/
/**
* 雙重檢測鎖模式
* @Auther: ZQB
* Date:2020/1/19
*/
public class Singleton3 {
private static volatile Singleton3 instace = null;
public static Singleton3 getInstance(){
if(instace == null){
Singleton3 sc;
synchronized (Singleton3.class){
sc = instace;
if (sc == null){
synchronized (Singleton3.class){
if (sc == null){
sc = new Singleton3();
}
}
instace = sc;
}
}
}
return instace;
}
private Singleton3(){}
public static void main(String[] args){
Singleton3 singleton3 = Singleton3.getInstance();
Singleton3 singleton31 = Singleton3.getInstance();
System.out.println(singleton3);
System.out.println(singleton31);
}
}
注意:通過反射和序列化可以獲取單例模式的對象