【设计模式九之多例模式】多例模式详解

  • Post author:
  • Post category:其他




细说多例模式

提示:

博主:章飞 _906285288的博客

博客地址:

http://blog.csdn.net/qq_29924041


## 细说多例模式

结合单例模式来说多例模式,单例模式相对来说比较容易理解一点,也就是在整个应用程序运行过程中,这个类的实例永远都是一个,好比如历朝历代,皇帝在大多数情况下都是只有一个,但是往往在程序运行过程中,我可能为了达到复用的效果,需要在一个池子中去选择对应的实例进行使用,这个时候多例模式也就应运而生了。

所谓多例模式其实也就是类的对象实例是有多个,但是这个多个也要区别于无限个,当然,如果一个类的对象可以有无限个的话,那能不能叫多例呢??这个可能就需要区别多例模式的特点了

所谓多例(Multiton Pattern)实际上就是单例模式的自然推广,属于对象

创建类型的模式,多例模式其实就是限制了对象的数量,并且有可能对对象进行重复使用


特点:


1:多例可以有多个实例

2:

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



多例类场景



场景一:

引用设计模式之禅中的案例,一般情况下,一个王朝的皇帝其实都是只有一个,但是在历史上,大明王朝在土木堡之变中被瓦刺俘虏的皇帝,皇帝突然有两个,一个执政,另外一个则被俘虏了。当俘虏皇帝获救之后,这个时候王朝有两个皇帝。这两个皇帝其实也就对应了两个对象实例,多例模式下的现实场景。



场景二:

在java学习过程中,有一个池子的概念一直存在,好比作线程池,数据库连接池,这个池子是用来对线程,或者数据库连接对象进行管理的,第一,限制了池子中的对象数量,第二就是能够在使用过程中达到复用的效果,线程中的线程在执行完毕后,不会被直接回收掉,而会切换成等待状态,等待下一个任务提交,执行。数据库连接池也是如此,数据库操作在连接的时候,如果对数据库操作完毕后,会把资源释放,然后等待下一个数据库操作进行连接。这种设计其实是将对象的应用最大化了,避免了每次连接的时候都需要去创建一个对象。造成对象冗余或者内存升高。



上代码



代码一
package src.com.zzf.designpattern.multitionpattern.demo1;


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

public class Emperor {
	private static final int maxNumberOfEmperor = 2;
	private static ArrayList emperorInfoList = new ArrayList(maxNumberOfEmperor);
	private static ArrayList emperorList = new ArrayList(maxNumberOfEmperor);
	
	private static int countNumofEmperor = 0;
	
	static{
		for(int i = 0; i < maxNumberOfEmperor ; i++){
			emperorList.add(new Emperor("第"+i+"皇帝"));
		}
	}
	
	
	private Emperor(){
		
	}
	
	private Emperor(String info){
		emperorInfoList.add(info);
	}
	
	public static Emperor getInstance(int num){
		countNumofEmperor = num;
		if (num == 0) {
			return (Emperor) emperorList.get(0);
		}else if(num == 1){
			return (Emperor) emperorList.get(1);
		}else{
			System.out.println("error");
			return null;
		}
	}
	
	  public static Emperor getInstance(){  
	        Random random=new Random();  
	        countNumofEmperor=random.nextInt(maxNumberOfEmperor);  
	        return (Emperor)emperorList.get(countNumofEmperor);  
	  }  
	
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		return (String) emperorInfoList.get(countNumofEmperor);
	}
}

package src.com.zzf.designpattern.multitionpattern.demo1;


/**
 *多例模式
 *所谓多例(Multiton Pattern)实际上就是单例模式的自然推广,属于对象
 *创建类型的模式,多例模式其实就是限制了对象的数量,并且有可能对对象进行重复使用
 *
 *特点:
 *1:多例可以有多个实例
 *2:多例类必须能够自我创建并管理自己的实例,并且向外界提供自己的实例
 * @author Administrator
 *
 */
public class MultiPatternTest {
	public static void main(String[] args) {
		Emperor mEmperor = Emperor.getInstance(0);
		System.out.println(mEmperor.toString());
		mEmperor = Emperor.getInstance(1);
		System.out.println(mEmperor.toString());
		mEmperor = Emperor.getInstance(2);
	}
}


代码二
package src.com.zzf.designpattern.multitionpattern.demo2;

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

public class SQLConnectionPools {
	private static int maxNumOfConnection= 8;
	private static ArrayList<String> connectionInfoList = new ArrayList<>(maxNumOfConnection);
	private static ArrayList<SQLConnectionPools> connArrayList = new ArrayList<>(maxNumOfConnection);
	private static int currNumOfConnection =0;
	
	private SQLConnectionPools() {
		// TODO Auto-generated constructor stub
	}
	
	private SQLConnectionPools(String info) {
		connectionInfoList.add(info);
	}
	
	static{
		for (int i = 0; i < maxNumOfConnection; i++) {
			connArrayList.add(new SQLConnectionPools(i+"号连接"));
		}
	}
	
	public static SQLConnectionPools getInstance() {
		Random random = new Random();
		currNumOfConnection = random.nextInt(maxNumOfConnection);
		return connArrayList.get(currNumOfConnection);
	}
	
	public void connectionInfo() {
		System.out.println(connectionInfoList.get(currNumOfConnection));
	}
	
}

package src.com.zzf.designpattern.multitionpattern.demo2;

public class Client {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		// TODO Auto-generated method stub
		 int userNum=10;  
	        for(int i=0;i<userNum;i++){  
	            //用户获取到的连接时随机的  
	            SQLConnectionPools conn= SQLConnectionPools.getInstance();  
	            System.out.print("第"+i+"个用户获得的连接是:");  
	            conn.connectionInfo();  
	        }  
	}

}

多例模式相对来说也是比较简单,现实生活场景中也有很多场景案例。所以也不过多的赘述,案例也简单的一批。如果我想打造一个属于自己的资源池,达到对象复用的效果,结合状态模式等,可以打造出属于自己的复用池。


欢迎继续访问,我的博客



版权声明:本文为qq_29924041原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。