一、GrilFriendClass 引言
N 先生很快就要大學畢業,大學四年忙於學(網)業(遊),也沒有找個女朋友。每每回家,家人都催促他趕快談一個,或者乾脆說要直接給 N 先生介紹物件。 有句話說什麼樣的年齡就該做什麼樣的事情,這句話放在當下還是很有道理的。可是 N 先生心中對成家立業是有自己的認識的,認為先立業而後成家,自己都沒條件過平凡的日子怎麼給另一半想要的生活呢。 但是由於家裡催的緊,N 先生就想到了租女友先應付家裡的姑姑阿姨們。
於是這一年每逢過節回家,N 先生都會帶新物件回家, 這年端午節,N 先生租安琪拉回家了,家裡人都誇著說 N 的物件看著很乖巧,
我們都知道這裡 N 的物件就是指的安琪拉。
同年中秋節,N 先生租孫尚香回家了,家裡人都誇著說 N 的物件像個大小姐。
我們都知道這裡 N 的物件就是指的孫尚香。
又到國慶節,N 先生租蔡文姬回家了,家裡人都誇著說 N 的物件十分卡哇伊。
我們都知道這裡 N 的物件就是指的蔡文姬。
這一年來,家人沒見到 N 先生時都會誇 N 的物件,但每次誇的物件都不一樣,這裡不是同一個物件。
當全域性系統每需要呼叫某個類 N 時,需要建立一個類 N 的新物件,即便建立的物件名稱相同,也不是同一個物件。
終於,畢業後的 N 先生在合適的年齡遇到了真愛不知火舞,確定了自己唯一的物件,這幾趟回家,家裡人提及 N 先生的物件時,都讚不絕口說大學生活不錯。
我們都知道,畢業後大家提到的 N 的物件都是不知火舞。這裡是同一個物件。
在軟體工程單例模式思想出來之前,每當開發者使用某個類時都會新建一個物件例項使用,優秀的開發者會在使用結束後釋放掉物件佔用的資源,單一般開發過程中很少在意這一點。於是這些沒被釋放資源的物件就成為了Java 虛擬機器裡的垃圾。單例模式就是保證了系統全域性只存在唯一的一個例項物件。確定了唯一物件的 N 先生,也代表了畢業前後 N 先生更加的成熟。
二、GrilFriendSingleton 例項演示
2-1 GrilFriendUnSingleton 非單例模式例項
在單例模式之前,我們會這樣寫一個Class ,寫基本屬性和類的相關方法,及建構函式或者帶引數的建構函式。下面以預設構造方法為例程式碼演示
package pers.niaonao.entity;
/**
* @author niaonao
* 非單例模式下的基本類
*/
public class GrilFriendUnSingleton {
//預設的構造方法
public GrilFriendUnSingleton() {
}
private String info = "我是你的新 GrilFriend";
/**
* 獲取物件資訊的方法
* @return
*/
public String getGrilFriend() {
return info;
}
}
複製程式碼
通過新建該類的實體物件來呼叫相關方法
package pers.niaonao.test;
import pers.niaonao.entity.GrilFriendUnSingleton;
/**
* @author niaonao
*
*/
public class TestGrilFriend {
public static void main(String[] args) {
//對實體類建立兩個物件
GrilFriendUnSingleton n_first_grilfriend = new GrilFriendUnSingleton();
GrilFriendUnSingleton n_next_grilfriend = new GrilFriendUnSingleton();
String info = "n_first_grilfriend 和 n_next_grilfriend";
//判斷物件是否是同一個例項
if (n_first_grilfriend != n_next_grilfriend) {
info += "\n\t不是同一個例項,是兩個不同的物件:"
+ "\n\t魔法為我而存在," + n_first_grilfriend.getGrilFriend()
+ "\n\t大小姐駕到," + n_next_grilfriend.getGrilFriend();
} else {
info += "\n\t是同一個例項,同一個物件:"
+ "\n\t會用不知火流的烈焰燒死你的呦," + n_first_grilfriend.getGrilFriend()
+ "\n\t會用不知火流的烈焰燒死你的呦," + n_next_grilfriend.getGrilFriend();
}
System.out.println(info);
}
}<span style="font-size:14px"></span><span style="color:#000000"></span>
複製程式碼
程式執行結果如下:
我們在系統全域性每需要使用該類時,都會在使用該類的地方通過構造方法新建類的實體物件。所以就會出現在系統全域性內,存在多個當前類的物件,並且其他地方就使用一次就不使用了,新建了一個物件佔用了一定的資源,但沒有釋放資源,這就造成資源的浪費,也是系統垃圾的一種。
2-2 GrilFriendBySingleton 單例模式例項
使用單例模式去寫一個class
package pers.niaonao.entity;
/**
* @author niaonao
* 單例模式下的基本類
*/
public class GrilFriendBySingleton {
//初始化靜態私有變數grilfriend
private static GrilFriendBySingleton grilfriend = null;
/**
* 構造單例模式基本方法getInstance()
* 呼叫該方法,會先判斷物件grilfriend是否不為null,即物件是否已存在,
* 若例項物件已存在則不再建立新物件,否則建立一個新物件給變數grilfriend。
*
* 保證當前類只存在一個實體物件。即單例模式
* @return grilfriend
*/
public static GrilFriendBySingleton getInstance() {
if (null == grilfriend)
grilfriend = new GrilFriendBySingleton();
return grilfriend;
}
//預設的構造方法
public GrilFriendBySingleton() {
}
private String info = "我是你的新 GrilFriend";
/**
* 獲取物件資訊的方法
* @return
*/
public String getGrilFriend() {
return info;
}
}
複製程式碼
測試類 TestGrilFriend 來測試單例模式
public static void main(String[] args) {
//通過單例模式建立出兩個實體常量
GrilFriendBySingleton n_first_grilfriend = GrilFriendBySingleton.getInstance();
GrilFriendBySingleton n_next_grilfriend = GrilFriendBySingleton.getInstance();
String info = "n_first_grilfriend 和 n_next_grilfriend";
//判斷物件是否是同一個例項
if (n_first_grilfriend != n_next_grilfriend) {
info += "\n\t不是同一個例項,是兩個不同的物件:"
+ "\n\t魔法為我而存在," + n_first_grilfriend.getGrilFriend()
+ "\n\t大小姐駕到," + n_next_grilfriend.getGrilFriend();
} else {
info += "\n\t是同一個例項,同一個物件:"
+ "\n\t會用不知火流的烈焰燒死你的呦," + n_first_grilfriend.getGrilFriend()
+ "\n\t會用不知火流的烈焰燒死你的呦," + n_next_grilfriend.getGrilFriend();
}
System.out.println(info);
}
複製程式碼
程式執行結果如下:
即使對 GrilFriendBySingleton 建立了兩個變數,但通過單例模式保證是同一個例項,即在記憶體中是存放在一個位置的一個物件。保證了系統全域性內只存在唯一的一個例項。這就是單例模式
三、Singleton Pattern 單例模式
通過前兩部分,應該對單例模式有一定的理解及認識,並能運用單例在實際開發中。下面說一下單例模式的定義,意義。
3-1 定義
Ensure a class only has one instance,and provide a global point of access to it.
GOF 對單例模式的定義是,保證一個類只有一個例項存在,同時提供能對該例項加以訪問的全域性訪問方法。
3-2 類圖
3-3 三要素
-
必須保證一個類只能有一個例項
-
必須是這個類自行建立這個例項
-
必須自行向整個系統提供這例項
3-4.優缺點
使用單例模式必然要了解其優缺點。
- 優點
客戶端使用單例模式類的例項,只需要呼叫一個單一的方法即可生成唯一的例項,節約了資源。
- 缺點
單例模式難以實現序列化 Serialization,所以採用單例模式的類很難被持久化,也不易通過網路傳輸,一般網路傳輸資料都會序列化物件相關的類。
單例模式採用靜態方法 static,不支援物件導向的三大特性之一的繼承,無法再繼承結構extend 中使用。
如果分散式叢集的環境下存在多個 Java 虛擬機器,不易確定具體的哪個單例在執行。
3-5 應用場景
一般會在Util 工具類中 service服務類中使用,部分entity 類中。
在多執行緒之間,公用同一個資源或操作同一個物件,這時候就用單例模式;在系統全域性都會使用到的,共享資源,全域性變數,可以使用單例模式;之所以說部分 entity 實體類會使用單例模式,是因為在大規模系統中,考慮到效能節約物件的建立時間,會使用單例模式。
3-6 說明
上面的GrilFriendBySingleton 實現中,我們通過getInstance() 保證只有一個例項存在,通過關鍵字 static 修飾getInstance() 方法,提供全域性訪問的方法。
我們得通過GrilFriendBySingleton 提供的方法去獲取單例,讓類自己建立例項,不能通過構造方法new GrilFriendBySingleton()再去建立,這就違背了單例模式的建立初衷。
3-7 標準單例程式碼演示
最後標準單例模式程式碼演示:
public class Singleton {
private static Singleton uniqueInstance = null;
private Singleton() {
// Exists only to defeat instantiation.
}
public static Singleton getInstance() {
if (uniqueInstance == null) {
uniqueInstance = new Singleton();
}
return uniqueInstance;
}
// Other methods...
}
複製程式碼
原文連結:http://blog.csdn.net/niaonao/article/details/79500198
更多
相信自己,沒有做不到的,只有想不到的
微信公眾號:終端研發部