单例模式:getInstance() vs 传递单例对象?
Singleton Pattern: getInstance() vs Passing the singleton object?
使用单例模式的正确/最流行的方法是什么。
- 限制人数调用 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());
}
}
- 不要传递单例对象。而是在每个 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());
}
}
- 甚至不要将引用保存为实例变量,而是在需要对象的任何地方使用 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
解决,这个概念在这里有很好的描述:
- Inversion of Control Containers and the Dependency Injection pattern
- Unit Testing 101: Inversion Of Control
阅读以上内容后,选择选项 .1
应该很容易,其中所有 classes 都在构造函数中获取所需依赖项的引用。您甚至可以为您需要的行为创建一个 interface
并在 SingletonClass
中实现它。现在你明白了,class 实现了 Singleton 模式这一事实并没有使它变得特别,我们应该像其他 classes 一样注入它们。使用 DI
的所有好处都可以应用到您的 class.
只需将其与 .3
进行比较,您就需要编写一个测试来模拟一些东西。在 .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());
}
}
- 不要传递单例对象。而是在每个 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());
}
}
- 甚至不要将引用保存为实例变量,而是在需要对象的任何地方使用 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
解决,这个概念在这里有很好的描述:
- Inversion of Control Containers and the Dependency Injection pattern
- Unit Testing 101: Inversion Of Control
阅读以上内容后,选择选项 .1
应该很容易,其中所有 classes 都在构造函数中获取所需依赖项的引用。您甚至可以为您需要的行为创建一个 interface
并在 SingletonClass
中实现它。现在你明白了,class 实现了 Singleton 模式这一事实并没有使它变得特别,我们应该像其他 classes 一样注入它们。使用 DI
的所有好处都可以应用到您的 class.
只需将其与 .3
进行比较,您就需要编写一个测试来模拟一些东西。在 .1
.