單例模式與多例模式


單例模式:顧名思義,一個程序只有一個實例

多利模式:一個程序有多個實例。

單例模式中,最重要的是如何能夠避免多個實例的產生。最直接的方法就是限制使用構造函數,然后定義統一的構造方法。使用《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("我就是皇帝某某某....");
    }
}
View Code

      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");
        }
    }
}
View Code

      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;
}
}
View Code

      改進:

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;
}
}
View Code

      改進方法也很簡單,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));
}
}
View Code

      注意,作者這里維護的不是一個列表,而是兩個,意思差不多,領會精神哈。獲得實例的時候,隨機獲取

      測試:

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();
}
}
}
View Code

      oye,剛打電話把中國移動罵了,感覺不錯。真心感覺看《Java設計模式》這本書的收獲很大,一些編程的小技巧都很實用。

    


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM