只允许创建“n”个对象的类

3
这个问题类似于单例模式,但我需要创建一个只能允许'n'个对象的类。以下是我的代码。
  public class MSInt {

    private static MSInt instance = null;

    private static int count = 0;

    private MSInt()
    {

    }


    public static MSInt getInstance()
    {
        if(count < 5){
            instance = new MSInt();
             count++;
             return instance;
        }
        else
        {
            return null;
        }

    }

}

这种方法可以工作,但我认为如果有更好的解决方案会更好。


你的解决方案是适当的,考虑到要求。显然,您需要以某种方式跟踪类的数量。将静态计数器作为类变量是合乎逻辑的。 - Kon
4
如果您在多线程环境中工作,请使用同步。 - Aniket Thakur
听起来不错。虽然你可能想把签名改为 public synchronized static MSInt getInstance() 以避免竞争条件。 - wns349
可能值得加入一个抛出异常的机制,当实例数量过多时,您可以为如果出现太多情况来自定义行为。将发布答案。 - Rudi Kershaw
你最终得出了什么是在你的情况下最好的结论吗?如果你的问题已经解决,请不要忘记点赞并接受一个答案。如果当前没有任何答案能够帮助到你,那么发布你自己的答案并将其选为正确答案也是完全可以接受的。 - Rudi Kershaw
5个回答

2

我认为这样做会更加简洁。你不需要任何计数器。 而且它看起来很好。

import java.util.ArrayList;

public class MSInt {

    private static int MAX_OBJS = 10;

    private static ArrayList<MSInt> instances = new ArrayList<MSInt>(MAX_OBJS);

    private MSInt() {}

    public static MSInt mkInstance() {
        if(instances.size() < MAX_OBJS){
            MSInt obj = new MSInt();
            instances.add(obj);
            return obj;
        } else {
            return null;
        }
    }

    public static ArrayList<MSInt> getInstances() {
        return instances;
    }

}

这里使用额外的ArrayList有什么用处? - Siva
“你不需要任何计数器”,但是MAX_OBJS难道不是完全相同的吗? - bschandramohan
你不打算从类内部使用这些实例吗? - Tristan
@ChandraMohan 它没有在计数,是吗? :P - Tristan
+1,集合/数组非常重要,否则你的一个对象可能会被垃圾回收移除,而静态计数器不会反映出这种变化。个人而言,我更喜欢使用数组,因为你可以在数组中定义最大值,而不是作为单独的变量。 - Rudi Kershaw

0

你的代码是:

        private static MSInt instance = null;

这是覆盖方法; 使用方式如下数组:

       private static MSInt[] instance = null;

并使用for循环:

  for(int i=0;i<5;i++)
   {
        instance[i] = new MSInt();
        return instance[i];
   }

0
使用数组或集合意味着垃圾回收不会在您不知情的情况下删除任何实例,并且这意味着如果需要,您可以稍后检索实例。使用MSInt[]可能是最实用的,因为它已经能够确保只存在一定数量的对象。然后,getInstance()方法遍历数组,如果找到一个空槽,则创建一个新实例,将其放入空槽中并返回结果。
public class MSInt {

    private static MSInt[] instances = new MSInt[10];

    private MSInt(){ }

    public synchronized static MSInt getInstance() /*throws TooManyException*/{          
        for(int i = 0 ; i<instances.length() ; i++){
             if(instances[i]==null){
                 MSInt ms = new MSInt();
                 instances[i] = ms;
                 return ms;  
             }
        }
        // throw new TooManyException("There are already 10 instances of MSInt");
        return null;          
    }
}

一些异常处理可能也会很有用。您可以抛出自定义异常来显示已经存在太多实例的情况。这将使其更易于管理,因为您可以为数组已满的情况定义更强大的自定义行为。通过删除上面类中的注释并创建下面的类,应该可以很好地解决该问题。

public class TooManyException extends Exception {

  public TooManyException(String message){
     super(message);
  }

}

希望这能有所帮助。

0

我建议您使用装饰器模式

因此,创建一个类LimitedList<T> extends AbstractList<T>并覆盖add方法以检查是否超出大小限制

我已经将代码放在这里(gist)


0
一些建议:
  1. public static MSInt getInstance() 替换为 public static MSInt getInstance(int number)。这样,您每次都可以指定要获取的对象。
  2. 定义实例之间的差异。您的实例具有哪些属性?在您的示例中,所有对象看起来都是相同的 - 不清楚为什么需要多个对象。
  3. 考虑初始化。您是否需要延迟初始化,或者可以在类初始化中初始化所有实例。然后,您可以将它们声明为 public static final 并禁止定义 getInstance()

顺便说一下,enum 是一个恰好有 n 个实例的类(按设计)。很可能将 MSInt 定义为 enum 对您来说是最方便的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接