所谓多例(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)); } }
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(); } } }