讀秦小波《設計模式之禪》 -- 單例模式
來源:程序員人生 發布時間:2015-01-04 08:54:43 閱讀次數:3375次
新年第1天,在這里首先要祝大家新年快樂!
這篇文章中,介紹的是非常重要,也是非常經常使用的1種設計模式 -- 單例模式。例如,我們在電腦上登錄QQ的時候,同1個QQ號碼就只能登錄1次,而不可能出現1個號碼可以登錄兩次的情況;再好像我現在聽歌用的播放器,我也只能打開它1次,當它在運行的時候,我不能夠同時運行兩個播放器客戶端。。。等等的這些模式都是單例的,即它能保證1個類就只有1個實例對象。
這里應用書中的例子去解釋構造單例的方法。
1個國家需要有1個皇帝,并且這個皇帝就只能有1個,那末,很明顯,它是單例的。我們需要構造1個皇帝類,且這個皇帝類只能有1個實例對象,那末,這里就會出現1個限制,即這個類的構造方法需要是私有的(private),否則,我們可以任意的生成對象。且這個類需要有1個靜態方法(static),當我們需要這個類的對象時,就能夠利用這個方法去獲得類對象。
好吧,看下具體的實現吧:
public class __Q_Y_Emperor {
/*這樣設計可以保證它是線程安全的*/
private static __Q_Y_Emperor _Emperor = new __Q_Y_Emperor();
private __Q_Y_Emperor()
{
}
public static __Q_Y_Emperor __Q_Y_GetInstance()
{
return _Emperor;
}
public static void __Q_Y_Talk()
{
System.out.println("i am Qinyi Zhang...");
}
}
這個類的實現就是利用到單例模式,固然,這里只是單例模式的1種實現方式。
我們需要1個測試函數,測試下這個單例模式是不是好用,這里,場景是有幾個大臣找皇帝,然后,每個大臣找到的都是同1個皇帝。
public class __Q_Y_EmperorMain {
/**
* @param args
*/
@SuppressWarnings("static-
access")
public static void main(String[] args) {
// TODO Auto-generated method stub
int _Minister = 5;
for (int i = 0; i != _Minister; ++i)
{
/*獲得的實例對象都是同1個*/
__Q_Y_Emperor _Emperor = __Q_Y_Emperor.__Q_Y_GetInstance();
_Emperor.__Q_Y_Talk();
}
}
}
我們運行下這個主函數,得到以下的結果:
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
i am Qinyi Zhang...
下面,看下類圖是怎樣的,很簡單,沒有繼承關系之類的
書中從單例模式又引伸出了1個叫 “多例模式” 的設計方法,即1個類能產生多個對象,但是對象的個數是有限制的。 也一樣是皇帝的例子,只是這個例子中出現了多個皇帝,每一個大臣可能找到的是不同的皇帝。
好吧,這個也是很容易實現的:
public class __Q_Y_MultiEmperor {
private final static int _MaxNumOfEmperor = 3;
private static ArrayList<String> _EmperorName = new ArrayList<String>();
private static ArrayList<__Q_Y_MultiEmperor> _EmperorList = new ArrayList<>();
private static int _CurrentNumOfEmperor = 0;
private __Q_Y_MultiEmperor()
{
}
private __Q_Y_MultiEmperor(String _name)
{
_EmperorName.add(_name);
}
static
{
/*多例模式,對象個數是有限制的*/
for (int i = 0; i != _MaxNumOfEmperor; ++i)
{
_EmperorList.add(new __Q_Y_MultiEmperor("num " + (i + 1)));
}
}
public static __Q_Y_MultiEmperor __Q_Y_GetInstance()
{
Random _randrom = new Random();
_CurrentNumOfEmperor = _randrom.nextInt(_MaxNumOfEmperor);
return _EmperorList.get(_CurrentNumOfEmperor);
}
public static void __Q_Y_Talk()
{
System.out.println(_EmperorName.get(_CurrentNumOfEmperor));
}
}
測試函數:
public class __Q_Y_MultiMain {
/**
* @param args
*/
@SuppressWarnings("static-
access")
public static void main(String[] args) {
// TODO Auto-generated method stub
int _Minister = 10;
for (int i = 0; i != _Minister; ++i)
{
__Q_Y_MultiEmperor _Emperor = __Q_Y_MultiEmperor.__Q_Y_GetInstance();
_Emperor.__Q_Y_Talk();
}
}
}
類圖:
最后,運行下這個例子吧:
num 3
num 2
num 2
num 2
num 3
num 1
num 2
num 2
num 1
num 1
生活不易,碼農辛苦
如果您覺得本網站對您的學習有所幫助,可以手機掃描二維碼進行捐贈