【設(shè)計模式】之單例模式
作者:xcbeyond
瘋狂源自夢想,技術(shù)成就輝煌!微信公眾號:《程序猿技術(shù)大咖》號主,專注后端開發(fā)多年,擁有豐富的研發(fā)經(jīng)驗,樂于技術(shù)輸出、分享,現(xiàn)階段從事微服務(wù)架構(gòu)項目的研發(fā)工作,涉及架構(gòu)設(shè)計、技術(shù)選型、業(yè)務(wù)研發(fā)等工作。對于Java、微服務(wù)、數(shù)據(jù)庫、Docker有深入了解,并有大量的調(diào)優(yōu)經(jīng)驗。
單例模式(Singleton Pattern):
確保某個類只有一個對象。單例類的構(gòu)造器是私有的(private),避免外界利用構(gòu)造器直接創(chuàng)建出任意多的實例。由于構(gòu)造器是private的,因此單例類是不能被繼承。
特點:
1>、單例類只能有一個實例。
2>、單例類必須自己創(chuàng)建自己的唯一實例。
3>、單例類必須給所有其他對象提供這一實例。
單例模式分三種:懶漢式單例、餓漢式單例、登記式單例三種。
1、餓漢式單例
package 單例模式;
/**
* 餓漢式單例:自己將自己實例化
* 在這個類被加載時,靜態(tài)變量instance會被初始化,此時類的私有構(gòu)造器被調(diào)用,這時單例類的唯一實例就被創(chuàng)建了。
* @author xcbeyond
* @date 2012-5-1 上午11:56:26
*/
public class EagerSingleton {
private static final EagerSingleton instance = new EagerSingleton();
//私有構(gòu)造器
private EagerSingleton() {
}
public static EagerSingleton getInstance() {
return instance;
}
}
2、懶漢式單例
與餓漢式單例不同的是,懶漢式單例類在第一次被引用時將自己實例化。如果加載器是靜態(tài)的,那么在懶漢式單例類被加載時不會將自己實例化。
package 單例模式;
/**
* 懶漢式單例
* @author xcbeyond
* @date 2012-5-1 下午12:23:54
*/
public class LazySingleton {
private static LazySingleton instance = null;
//私有構(gòu)造器
private LazySingleton(){
}
//靜態(tài)工廠方法,返回此類的唯一實例
synchronized public static LazySingleton getInstance () {
if(instance == null ) {
instance = new LazySingleton();
}
return instance;
}
}
3、登記式單例
為了克服餓漢式單例類和懶漢式單例類不可繼承的缺點,于是引入了登記式單例類。
package 單例模式;
import java.util.HashMap;
/**
* 登記式單例類:克服了餓漢式和懶漢式單例類的不可繼承的缺點。
* @author xcbeyond
* @date 2012-5-1 下午12:35:23
*/
public class RegisterSingleton {
private static HashMap reg = new HashMap();
static {
RegisterSingleton x = new RegisterSingleton();
reg.put(x.getClass().getName(), x);
}
//保護(hù)的默認(rèn)構(gòu)造器
protected RegisterSingleton () {
}
//靜態(tài)工廠方法,返回此類唯一的實例
public static RegisterSingleton getInstance(String name) {
if(name == null) {
name = "RegisterSingleton";
}
if(reg.get(name)==null) {
try{
reg.put(name, Class.forName(name).newInstance());
}catch(Exception e) {
System.out.println("Error happened");
}
}
return (RegisterSingleton)reg.get(name);
}
}