不使用单例将类限制为一个实例?

时间:2014-03-28 22:55:06

标签: java singleton

我不想使用单例,但我根本不能允许我的类的多个实例。

你认为这是一个好方法,如果不是,那么更好的方法是什么?

public class SoundSystem {

    private static boolean instanceCreated = false;

    public SoundSystem() {
        if(instanceCreated) {
            throw new IllegalStateException("Only one instance can be created.");
        }

        instanceCreated = true;
    }
}

4 个答案:

答案 0 :(得分:4)

这个 是一个单身人士,即使你没有在"传统"方式。我不推荐这种方法,我认为你应该找到另一种方法。

例如,为什么不在程序启动时创建单个SoundSystem实例?您不需要明确强制执行其单一操作,只需将该实例传递给需要访问音响系统的其他对象。作为奖励,如果您有一天需要它,这也可以让您轻松支持不同类型的SoundSystem(即使您不需要这样做,这也是一个很好的额外好处)。

除此之外,如果您尝试初始化多个SoundSystem,OpanAL初始化本身是否会失败?如果没有,那么就没有理由设置人为限制。如果是这样,那么你可以让OpanAL确定什么是错误并且不是错误。但无论如何,如果您只是创建一个实例并将其传递出去而不是让所有应用程序类自己查询实例,那么风险就不会有风险。

小心你不要落入这里的XY Problem陷阱。单身人士本身并不是邪恶,但由于某些原因,他们经常被误用,因此对他们的一般建议。通常有一种更清洁的方式,这些更清洁的方式通常会带来许多额外的好处。考虑一下您试图解决的实际问题/您在此尝试避免的情况。

答案 1 :(得分:2)

不,这不是一个好方法。

让我们在多线程的背景下快速举例。

线程1实例化SoundSystemif(instanceCreated)返回false,然后将instanceCreated更改为true,调度程序中断线程1.现在线程2也可以实例化SoundSystem,因为{{ 1}}当时是假的。

但最后,两个线程都会有不同的实例。

答案 2 :(得分:0)

如果您愿意制作所有字段final,则可以使用枚举。这也有一些“代码味道”。它可以防止出现多线程问题,但确实存在所有SoundSystem实例变量都需要最终的限制。

public enum SoundSystem {
    INSTANCE("Hello", "World");

    private final Object field1;
    private final Object field2;

    private SoundSystem(Object field1, Object field2) {
        this.field1 = field1;
        this.field2 = field2;
    }

    @Override
    public String toString() {
        return field1.toString() + "  " + field2.toString();
    }

    public Object getField1() {
        return this.field1;
    }

    public Object getField2() { 
        return this.field2;
    }

    //etc., etc.
}

然后,您可以使用SoundSystem.INSTANCE来访问您的单件商品

答案 3 :(得分:0)

您发布的解决方案允许种类繁多的种族条件"。试图同时创建SoundSystem的两个实体可能最终都创建一个实例。

也许让SoundSystem静态的所有方法和变量都可以满足您的需求,但如果没有更多信息,很难知道。