简体   繁体   English

如何强制构造函数只调用一次没有单例模式?

[英]How to force constructor is only called once without singleton pattern?

I always read singleton pattern is an anti pattern etc. But I spent nearly a day to find out, that a class had something like a cyclic dependency in construction leading to more than one object, where only one was allowed for the application. 我总是读单身模式是一种反模式等。但是我花了将近一天时间才发现,一个类在构造中有类似循环依赖的东西,导致多个对象,其中只有一个被允许用于应用程序。 That's why I want to verify this never happens again and don't know how to do that without the singleton pattern. 这就是为什么我想要验证这种情况再也不会发生,并且如果没有单例模式就不知道如何做到这一点。

public class Application {
    private SingletonModule module;

    public void getModule() {
        if(module == null) {
            module = new SingletonModule(getDependency());
        }
        return module;
    }

    private Dependency getDependency() {
        return new Dependency(getModule());
    }


}

public class Dependency {
    public Dependency(SingletonModule module) {
        System.out.println(module.getAttribute()); // is more complex of course...
    }
}

public class SingletonModule {
    public Dependency dep;
    public String attribute;

    public SingletonModule(Dependency dep) {
        this.dep=dep;
    }

    public String getAttribute() {
        return attribute;
    }

}

No the problem is getModule() is called from outside, ie 没有问题是从外部调用getModule() ,即

public class Runner {
     public Runner() {
         Application app = new Application();
         app.getModule().getAttribute();
     }
}

The constructor can check: 构造函数可以检查:

public class OnlyOne {
    static count = 0;
    public OnlyOne() {
        if (count > 0) throw ...
        count++;
        ...
    }
}

or a factory method: 或工厂方法:

public class OnlyOne {
    static count = 0;
    public static OnlyOne make() {
        if (count > 0) throw ...
        count++;
        return new OnlyOne();
    }
    private OnlyOne() { ...}
}

Update: Ideally, creation of this class would be so simple, eg, when program starts and then passed as dependency, that this check would unnecessary. 更新:理想情况下,创建此类将非常简单,例如,当程序启动然后作为依赖项传递时,此检查将不再必要。 But if creation happens in a more complex situation, as I assume yours is, then it's a useful safety check. 但是如果创造发生在更复杂的情况下,正如我所假设的那样,那么这是一个有用的安全检查。

There is nothing wrong with singletons if that's what your application calls for. 单身者没有任何问题,如果这是您的申请所要求的。 Static variables exist for a reason. 静态变量存在是有原因的。 If someone is demanding you do this in an OO way you can make them look ridiculous by creating an object called NotASingletonChecker that performs sixteen checks on a 1-variable-long array, pushing and popping instances of your "NotASingleton" class to it. 如果有人要求你以OO的方式做到这一点,你可以通过创建一个名为NotASingletonChecker的对象使它们看起来很荒谬,该对象对1-variable-long数组执行16次检查,将“NotASingleton”类的实例推送和弹出。 Make sure you do extensive garbage collection with a "NotSingletonGarbageCollector" class. 确保使用“NotSingletonGarbageCollector”类进行大量垃圾收集。

Singleton is not an "anti-pattern". 单身人士不是一个“反模式”。 I find this word too...strong. 我觉得这个词太强了......

It is a design pattern as others. 这是一种与其他人一样的设计模式。
The point is just that it could lead to a very bad practice when overused, for those reasons . 关键在于,由于这些原因 ,在过度使用时可能导致非常糟糕的做法。
That's why a lot of good developers avoid it when they aren't forced to use it. 这就是为什么许多优秀的开发人员在不被迫使用它时会避免它的原因。

The antipattern would be especially to prevent a natural class (whose constructor is reachable) to spawn more than one object. 反模式尤其是为了防止自然类(其构造函数可以访问)生成多个对象。

Just make use of the singleton when it makes sense, and in this case...it would. 只要在有意义的情况下使用单身人士,在这种情况下......就可以了。

My preferred solution would be (I imagine you may use Spring..or Guice etc...) to instantiate a bean as singleton. 我首选的解决方案是(我想你可以使用Spring..or Guice等......)将bean实例化为singleton。 That way, you will end up with a perfect singleton without all these constraints of testing etc.. since your class would appear as a perfect non-singleton-designed class. 这样,你就会得到一个完美的单身人士,而不受测试等所有这些限制。因为你的课程看起来像一个完美的非单身设计课程。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM