单例模式:getInstance() vs 传递单例对象?

Singleton Pattern: getInstance() vs Passing the singleton object?

使用单例模式的正确/最流行的方法是什么。

  1. 限制人数调用 getInstance() 的次数,最好只调用一次,然后在实例化期间将对象传递给其他 classes?
class SingletonClass {
// Implementataion
}

class MainClass {
    private SingletonClass singletonClassObject;

    public MainClass() {
        singletonClassObject = SingletonClass.getInstance();
        new SomeClass(singletonClassObject).doSomething();
        new SomeOtherClass(singletonClassObject).doSomethingElse();
    }
}

class SomeClass {
    private SingletonClass singletonClassObject;

    public SomeClass(SingletonClass singletonClassObject) {
        this.singletonClassObject = singletonClassObject;
    }

    public void doSomething() {
        System.out.println(singletonClassObject.getStuff());
    }
}

class SomeOtherClass {
    private SingletonClass singletonClassObject;

    public SomeOtherClass(SingletonClass singletonClassObject) {
        this.singletonClassObject = singletonClassObject;
    }

    public void doSomethingElse() {
        System.out.println(singletonClassObject.getStuff());
    }
}

  1. 不要传递单例对象。而是在每个 class 中调用获取对象引用并将引用保存为实例变量并在需要时使用它。
class SingletonClass {
// Implementataion
}

class MainClass {
    public MainClass() {
        new SomeClass().doSomething();
        new SomeOtherClass().doSomethingElse();
    }
}

class SomeClass {
    private SingletonClass singletonClassObject;

    public SomeClass() {
        singletonClassObject = SingletonClass.getInstance();
    }

    public void doSomething() {
        System.out.println(singletonClassObject.getStuff());
    }
}

class SomeOtherClass {
    private SingletonClass singletonClassObject;

    public SomeOtherClass() {
        singletonClassObject = SingletonClass.getInstance();
    }

    public void doSomethingElse() {
        System.out.println(singletonClassObject.getStuff());
    }
}

  1. 甚至不要将引用保存为实例变量,而是在需要对象的任何地方使用 SingletonClass.getInstance()。
class SingletonClass {
// Implementataion
}

class MainClass {
    public MainClass() {
        new SomeClass().doSomething();
        new SomeOtherClass().doSomethingElse();
    }
}

class SomeClass {
    public SomeClass() {
    }

    public void doSomething() {
        System.out.println(SingletonClass.getInstance().getStuff());
    }
}

class SomeOtherClass {
    public SomeOtherClass() {
    }

    public void doSomethingElse() {
        System.out.println(SingletonClass.getInstance().getStuff());
    }
}

这些方法如何相互比较 w.r.t。更好的设计、可测试性等?哪个更好?为什么?

这样看:您在质疑编译器识别静态最终引用可以编译为内联引用的能力。

我猜编译器会将 getInstance() 转换为内联引用。当您按值传递引用时,编译器会识别出您有意为自己创建额外的工作,并且当您传递它时它会在堆栈上创建一个额外的引用,我不太相信。

我猜 getInstance() 会更有效率。

如果我们暂时假设 SingletonClass 不是单例并且我们没有通过调用 static 方法获得实例,我们将面临另一个问题,如何 link 这些 class一起。这个问题由 Dependency Injection 解决,这个概念在这里有很好的描述:

阅读以上内容后,选择选项 .1 应该很容易,其中所有 classes 都在构造函数中获取所需依赖项的引用。您甚至可以为您需要的行为创建一个 interface 并在 SingletonClass 中实现它。现在你明白了,class 实现了 Singleton 模式这一事实并没有使它变得特别,我们应该像其他 classes 一样注入它们。使用 DI 的所有好处都可以应用到您的 class.

只需将其与 .3 进行比较,您就需要编写一个测试来模拟一些东西。在 .1.

的情况下,这将是更不愉快的任务