1. 程式人生 > >單例模式和多例模式的區別

單例模式和多例模式的區別

單例多例需要搞明白兩個問題:
1. 什麼是單例多例;
2. 如何產生單例多例;
3. 為什麼要用單例多例
4. 什麼時候用單例,什麼時候用多例;
1. 什麼是單例、多例:
所謂單例就是所有的請求都用一個物件來處理,比如我們常用的service和dao層的物件通常都是單例的,而多例則指每個請求用一個新的物件來處理,比如action; 

一、單例模式和多例模式說明:

1.         單例模式和多例模式屬於物件模式。

2.         單例模式的物件在整個系統中只有一份,多例模式可以有多個例項。

3.         它們都不對外提供構造方法,即構造方法都為私有。

二、應用舉例

1.         單例模式舉例:

package com.solid.pattern;

import java.util.Locale;

import java.util.ResourceBundle;

/**

 * 單例模式

 */

public class Singleton { 

    private static Singleton singleton = new Singleton();

    private Singleton() {}

    public static Singleton getInstance() {

       return singleton;

    }

   

    /**

     * 獲取配置檔案的值

     * @param key

     */

    public void getMessage(String key) {

       Locale locale = new Locale(key);

       ResourceBundle res = ResourceBundle.getBundle("res_zh_CN");

       String message = res.getString(key);

       System.out.println(message);

    }

}

 

package com.solid.pattern;

/**

 * 單例模式測試

 * @author solid

 *

 */

public class TestSingleton {

 

    private static Singleton singleton;

   

    public static void main(String[] args) {

       singleton = Singleton.getInstance();

       singleton.getMessage("title");

    }

}

 

2.         多例模式舉例:

package com.solid.pattern;

/**

 * 多例模式

 * @author solid

 *

 */

public class Multiton {

 

    private static Multiton multi1 = new Multiton();

    private static Multiton multi2 = new Multiton();

   

    private Multiton() {}

   

    public static Multiton getInstance(int key) {

       if(key == 1) {

           return multi1;

       } else {

           return multi2;

       }

    }

   

    /**

     * 獲取1—6之間的隨機數

     */

    public void getValue() {

       int value = (int)(Math.random()*6+1);

       System.out.println(value);

    }

}

 

package com.solid.pattern;

/**

 * 多例模式測試

 * @author solid

 *

 */

public class TestMultiton {

    private static Multiton multi1;

    private static Multiton multi2;

    public static void main(String[] args) {

       multi1 = Multiton.getInstance(1);

       multi2 = Multiton.getInstance(2);

      

       multi1.getValue();

       multi2.getValue();

    }

}


2. 如何產生單例、多例:
    在通用的SSH中,單例在spring中是預設的,如果要產生多例,則在配置檔案的bean中新增scope="prototype"; 

我就告訴你昨天我得問題你估計就明白了

我沒用scope="prototype"就出現上面得驗證問題了 連續點提交就這樣
我新增後 不論怎麼點都只會出現一個驗證提示

3. 為什麼用單例、多例:
    之所以用單例,是因為沒必要每個請求都新建一個物件,這樣子既浪費CPU又浪費記憶體;
   之所以用多例,是為了防止併發問題;即一個請求改變了物件的狀態,此時物件又處理另一個請求,而之前請求對物件狀態的改變導致了物件對另一個請求做了錯誤的處理;
    用單例和多例的標準只有一個:
    當物件含有可改變的狀態時(更精確的說就是在實際應用中該狀態會改變),則多例,否則單例;
4. 何時用單例?何時用多例?
    對於struts2來說,action必須用多例,因為action本身含有請求引數的值,即可改變的狀態;
  而對於STRUTS1來說,action則可用單例,因為請求引數的值是放在actionForm中,而非action中的;
   另外要說一下,並不是說service或dao一定是單例,標準同第3點所講的,就曾見過有的service中也包含了可改變的狀態,同時執行方法也依賴該狀態,但一樣用的單例,這樣就會出現隱藏的BUG,而併發的BUG通常很難重現和查詢;