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

时间:2019-10-24 22:56:38

标签: java oop design-patterns singleton

什么是使用单例模式的正确/最受欢迎的方法。

  1. 限制号码。调用getInstance(),最好只调用一次,然后在实例化过程中将对象传递给其他类?
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 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());
    }
}

这些方法如何相互比较更好的设计,可测试性等?哪个更好?为什么?

2 个答案:

答案 0 :(得分:2)

如果我们暂时假设cucumber.runtime.java.guice.ScenarioScoped不是单例,并且没有通过调用SingletonClass方法获得实例,那么我们将面临另一个问题,即如何将这些类链接在一起。 static解决了这个问题,这里对此概念进行了很好的描述:

在阅读了上面的内容之后,应该容易选择选项Dependency Injection,其中所有类都在构造函数中获取对所需依赖项的引用。您甚至可以为所需的行为创建.1并在interface中实施。现在您知道,类实现Singleton模式的事实并没有使其特别,我们应该像其他类一样注入它们。使用SingletonClass可以带来的所有好处都可以应用于您的课程。

只需将其与DI进行比较,就需要编写一个需要模拟的地方的测试。比起.3来说,这将是更加令人不愉快的任务。

答案 1 :(得分:0)

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

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

我的猜测是getInstance()会更高效。