一个单例模式的变种形式—-可控多例模式

一个单例模式的变种形式—-可控多例模式

单例模式(Singleton),也叫单子模式,是一种常用的软件设计模式。在应用这个模式时,单例对象的类必须保证只有一个实例存在。许多时候整个系统只需要拥有一个的全局对象,这样有利于我们协调系统整体的行为。比如在某个服务器程序中,该服务器的配置信息存放在一个文件中,这些配置数据由一个单例对象统一读取,然后服务进程中的其他对象再通过这个单例对象获取这些配置信息。这种方式简化了在复杂环境下的配置管理。

实现单例模式的思路是:一个类能返回对象一个引用(永远是同一个)和一个获得该实例的方法(必须是静态方法,通常使用getInstance这个名称);当我们调用这个方法时,如果类持有的引用不为空就返回这个引用,如果类保持的引用为空就创建该类的实例并将实例的引用赋予该类保持的引用;同时我们还将该类的构造函数定义为私有方法,这样其他处的代码就无法通过调用该类的构造函数来实例化该类的对象,只有通过该类提供的静态方法来得到该类的唯一实例。

这里,我不想多说这个模式,而是说明另一种模式。

假设系统中出现这样的情况:系统中不仅仅只需要出现1个实例,而是最多只能出现2个或3个呢?单例模式明显就不能用了,怎么办,其实也很简单,修改单例的类,让其返回对象的函数检测系统中已存在的实例个数,如果超过了,就抛出异常,否则则返回一个实例。

另外,因为要严格控制系统中已创建实例的个数,就需要一个计数器,java和c++不同,没有析构函数,所以,就要求使用者调用一个释放的方法,来告诉系统已经消除了该实例。

既然已经想到了修改某个单例类,能不能更简单一些,创造一个框架性的东西,让想采用该模式设计的类,只要继承这套框架就可以使用了呢?也是可以的。具体是这样实现的,利用jdk1.5的模板功能,创造一个Count的模板类,该类负责统计数目和抛出异常,所有想使用这个模式的类,继承该Count类就可以了。具体请看下面的代码。

/**
 * 单例模式的变种,可以控制建立实例的数目
 *
 * 计数器类
 *
 * 如果超过建立制定数目的实例,则抛出MaxInstanceException异常
 *
 * @author roye( royelee_007@hotmail.com )
 * @version 0.1
 * @see MaxInstanceException
 */
class Count<T>{
 public static int objectNum = 0;
 
 private static int OBJECT_SUM = 1;
 
 protected Count() throws MaxInstanceException{
  //System.out.println("objectNum = " + objectNum);
  
  ++objectNum;
  
  if(objectNum > OBJECT_SUM){
   throw new MaxInstanceException();
  }
  
  init();
 }
 
 /*
  * 可以改变此函数来获得不同的初始化效果
  */
 protected void init(){
  //….
 }
 
 /*
  * 每一个实例被释放时,一定要调用这个函数,否则无法创建新的实例
  */
 public void release(){
  –objectNum;
 }
 
 /*
  * 指定某个类的最大实例数目,默认为1个实例
  */
 protected static void setObejctSum(int s){
  OBJECT_SUM  = s;
 }
}

class MaxInstanceException extends Exception{};

/*
 * 一个例子,请注意该类的构造函数和getInstance函数的形式。必须按照此形式,才能顺利采用Count的框架
 *
 * @author roye( royelee_007@hotmail.com )
 * @version 0.1
 * @see Count<T>
 */
class Print extends Count<Print>{
 private Print() throws MaxInstanceException{
 }
 
 public static Print getInstance() throws MaxInstanceException{
  //setObejctSum(2); //you can change max instance number here.
  
  return new Print();
 }
}

public class CountedInstanceTest{
 public static void main(String[] args){
  //first example shows how to create an instance without exception throwed.
  try{
   Print p = Print.getInstance();
   p.release();
   p = null;
   
   Print p1 = Print.getInstance();
   p1.release();
   p1 = null;   
  }catch(Exception e){
   e.printStackTrace();
  }
  
  //bad usage
  try{
   Print p = Print.getInstance();
   Print p1 = Print.getInstance();
  }catch(Exception e){
   e.printStackTrace();
  }
 }
}
 

 

One thought on “一个单例模式的变种形式—-可控多例模式

  1. wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling
    wow power leveling -229859120745546

Leave a Reply

Your email address will not be published. Required fields are marked *