代码改变世界

设计模式之多例模式

2013-07-15 10:36  youxin  阅读(1098)  评论(0编辑  收藏  举报

所谓多例(Multiton Pattern)实际上就是单例模式的自然推广。作为对象的创建模式,多例模式或多例类有以下的特点:
1、多例类可以有多个实例

2、多例类必须能够自我创建并管理自己的实例,并向外界提供自己的实例。

有上限多例模式一般类图:

public class Die {
      private static Die die1 = new Die();
        private static Die die2 = new Die();

        /**
         * 私有构造函数保证 外界 无法直接将此类实例化
         */
        private Die() {

        }
        /**
         * 工厂方法
         * @param i
         * @return
         */
       public static Die getInstance(int i)
       {
           switch(i)
           {
             case  1:
                 return die1;
                 
             case  2:
                 return die2;
             default:
                 return null;
           }
           
       }
       
       public synchronized int dice()
       {
           System.out.println("**********************");
           Date date=new Date();
           Random random=new Random(date.getTime());
           //random.nextINt()可能返回负数
           int value=Math.abs(random.nextInt()%6)+1;
           return value;
       }
        

}
public class DieTest {

    /**
     * @param args
     */
    public static void main(String[] args) {
        Die die1=Die.getInstance(1);
        Die die2=Die.getInstance(2);
        System.out.println(die1.dice());
        System.out.println(die2.dice());

    }

}

 

 

无上限多例模式

实例数目没有上限的多例模式叫无上限多例模式。
由于没有上限的多例类对实例的数目是没有限制的,因此,虽然这种多例模式是单例模式的推广,但是这种多例类并不一定能够回到单例类。
由于事先不知道要创建多少个实例,因此,必然使用聚集管理所有的实例。

 

多例模式典型的例子就是数据库线程池,下面我就模拟一下用户取得线程池中连接的简化场景:

先设计这个产生连接的类

 

package com.gy.designpattern.multition;

import java.util.ArrayList;
import java.util.Random;

/**
 * ClassName:MyConnections <br/>
 * Function: 这个类用于产生多个connection. <br/>
 * Reason:     TODO ADD REASON. <br/>
 * Date:     2012-7-4 上午11:45:54 <br/>
 * @author   gongyong
 * @version
 * @since    JDK 1.6
 * @see
 */
public class MyConnections {
    /**
     * maxNumOfConnection:允许产生的最大连接数.
     * @since JDK 1.6
     */
    private static int maxNumOfConnection = 5;
    /**
     * connectionInfoList:装所有连接信息(就是编号)的List.
     * @since JDK 1.6
     */
    private static ArrayList<String> connectionInfoList=new ArrayList<String>(maxNumOfConnection);
    /**
     * connectionList:装所有连接的List.
     * @since JDK 1.6
     */
    private static ArrayList<MyConnections> connectionList=new ArrayList<MyConnections>(maxNumOfConnection);

    /**
     * currNumOfConnection:当前的连接号.
     * @since JDK 1.6
     */
    private static int currNumOfConnection =0;


    //私有构造方法
    private MyConnections(){
    }

    //私有构造方法
    private MyConnections(String info){
        connectionInfoList.add(info);
    }


    //把所有的连接都产生出来
    static{
    for(int i=0;i<maxNumOfConnection;i++){
        //放在connectionList中的对象和connectionInfoList中的信息是一一对应的
        //当然,完全可以去掉这个connectionInfoList,在这个类中设一个变量来保存这个信息
        connectionList.add(new MyConnections("我是连接:"+i+"号"));
        }
    }

    /**
     * getInstance:返回任意一个连接. <br/>
     * @author gongyong
     * @return
     * @since JDK 1.6
     */
    public static MyConnections getInstance(){
        Random random=new Random();
        currNumOfConnection=random.nextInt(maxNumOfConnection);
        return (MyConnections)connectionList.get(currNumOfConnection);
    }

    /**
     * connectionInfo:返回当前连接的信息. <br/>
     * @author gongyong
     * @since JDK 1.6
     */
    public  void connectionInfo(){
        System.out.println(connectionInfoList.get(currNumOfConnection));
    }

}
View Code
package com.gy.designpattern.multition;
/**
 * ClassName:Client <br/>
 * Function: 这是客户端,用于获取连接. <br/>
 * Reason:     TODO ADD REASON. <br/>
 * Date:     2012-7-4 下午12:51:16 <br/>
 * @author   gongyong
 * @version
 * @since    JDK 1.6
 * @see
 */
public class Client {

    public static void main(String[] args){
        int userNum=10;
        for(int i=0;i<userNum;i++){

            //用户获取到的连接时随机的
            MyConnections conn= MyConnections.getInstance();
            System.out.print("第"+i+"个用户获得的连接是:");
            conn.connectionInfo();
        }
    }
}
View Code