單例模式:顧名思義,一個程序只有一個實例
多利模式:一個程序有多個實例。
單例模式中,最重要的是如何能夠避免多個實例的產生。最直接的方法就是限制使用構造函數,然后定義統一的構造方法。使用《Java設計模式》中皇帝的例子,一般只有一個例子:

/** * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you * all. 中國的歷史上一般都是一個朝代一個皇帝,有兩個皇帝的話,必然要PK出一個皇帝出來 */ public class Emperor { private static Emperor emperor = null; // 定義一個皇帝放在那里,然后給這個皇帝名字 private Emperor() { // 世俗和道德約束你,目的就是不讓你產生第二個皇帝 } public static Emperor getInstance() { if (emperor == null) { // 如果皇帝還沒有定義,那就定一個 emperor = new Emperor(); } return emperor; } // 皇帝叫什么名字呀 public static void emperorInfo() { System.out.println("我就是皇帝某某某...."); } }
static 成了這個程序的點睛之筆,同時只能有一個實例,並且通過同一的getInstance來得到該實例
測試程序:

/** * @author cbf4Life cbf4life@126.com I'm glad to share my knowledge with you * all. 大臣是天天要面見皇帝,今天見的皇帝和昨天的,前天不一樣那就出問題了! */ @SuppressWarnings("all") public class Minister { /** * @param args */ public static void main(String[] args) { // 第一天 Emperor emperor1 = Emperor.getInstance(); emperor1.emperorInfo(); // 第一天見的皇帝叫什么名字呢? // 第二天 Emperor emperor2 = Emperor.getInstance(); Emperor.emperorInfo(); // 第三天 Emperor emperor3 = Emperor.getInstance(); emperor2.emperorInfo(); // 三天見的皇帝都是同一個人,榮幸吧! if(emperor1==emperor2){ System.out.println("one"); } } }
ok,這個程序在多線程下可能出現致命錯誤,在判斷==的時候,可能會有多個線程同時請求,這樣的錯誤無法重現,非常難以查到。作者給了一個通用的例子和改進方法:

package com.cbf4life.singleton3; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 通用單例模式 */ @SuppressWarnings("all") public class SingletonPattern { private static SingletonPattern singletonPattern= null; //限制住不能直接產生一個實例 private SingletonPattern(){ } public SingletonPattern getInstance(){ if(this.singletonPattern == null){ //如果還沒有實例,則創建一個 this.singletonPattern = new SingletonPattern(); } return this.singletonPattern; } }
改進:

package com.cbf4life.singleton3; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 通用單例模式 */ @SuppressWarnings("all") public class SingletonPattern { private static final SingletonPattern singletonPattern= new SingletonPattern(); //限制住不能直接產生一個實例 private SingletonPattern(){ } public synchronized static SingletonPattern getInstance(){ return singletonPattern; } }
改進方法也很簡單,final修飾對象,直接進行定義。然后互斥鎖保護返回函數,一切ok,說實在的,比原先的看上去還簡單。
設計模式並不難於理解,重要的是能夠靈活使用在平時的程序實現中。
下面是多例模式:如果有多個皇帝呢?呵呵,維護一個鏈表不就行了

package com.cbf4life.singleton2; import java.util.ArrayList; import java.util.Random; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 中國的歷史上一般都是一個朝代一個皇帝,有兩個皇帝的話,必然要PK出一個皇帝出來。 * 問題出來了:如果真在一個時間,中國出現了兩個皇帝怎么辦?比如明朝土木堡之變后, * 明英宗被俘虜,明景帝即位,但是明景帝當上皇帝后樂瘋了,竟然忘記把他老哥明英宗削為太上皇, * 也就是在這一個多月的時間內,中國竟然有兩個皇帝! * */ 第 16 頁 您的設計模式 @SuppressWarnings("all") public class Emperor { private static int maxNumOfEmperor = 2; //最多只能有連個皇帝 private static ArrayList emperorInfoList=new ArrayList(maxNumOfEmperor); // 皇帝叫什么名字 private static ArrayList emperorList=new ArrayList(maxNumOfEmperor); //裝皇 帝的列表; private static int countNumOfEmperor =0; //正在被人尊稱的是那個皇帝 //先把2個皇帝產生出來 static{ //把所有的皇帝都產生出來 for(int i=0;i<maxNumOfEmperor;i++){ emperorList.add(new Emperor("皇"+(i+1)+"帝")); } } //就這么多皇帝了,不允許再推舉一個皇帝(new 一個皇帝) private Emperor(){ //世俗和道德約束你,目的就是不讓你產生第二個皇帝 } private Emperor(String info){ emperorInfoList.add(info); } public static Emperor getInstance(){ Random random = new Random(); countNumOfEmperor = random.nextInt(maxNumOfEmperor); //隨機拉出一個皇帝, 只要是個精神領袖就成 return (Emperor)emperorList.get(countNumOfEmperor); } //皇帝叫什么名字呀 public static void emperorInfo(){ System.out.println(emperorInfoList.get(countNumOfEmperor)); } }
注意,作者這里維護的不是一個列表,而是兩個,意思差不多,領會精神哈。獲得實例的時候,隨機獲取
測試:

package com.cbf4life.singleton2; /** * @author cbf4Life cbf4life@126.com * I'm glad to share my knowledge with you all. * 大臣們悲慘了,一個皇帝都伺候不過來了,現在還來了兩個個皇帝 * TND,不管了,找到個皇帝,磕頭,請按就成了! */ @SuppressWarnings("all") public class Minister { /** * @param args */ public static void main(String[] args) { int ministerNum =10; //10個大臣 for(int i=0;i<ministerNum;i++){ Emperor emperor = Emperor.getInstance(); System.out.print("第"+(i+1)+"個大臣參拜的是:"); emperor.emperorInfo(); } } }
oye,剛打電話把中國移動罵了,感覺不錯。真心感覺看《Java設計模式》這本書的收獲很大,一些編程的小技巧都很實用。