我最近在对一位同事进行代码审查时遇到了一种我以前从未见过的特殊模式。他发送一个单例作为函数中的参数,并将其作为成员保存在调用类中。
假设我有一个简单的单例类 Foo
public class Foo {
private static Foo instance;
private int counter;
private Foo(){}
public static Foo getInstance(){
if (instance == null){
instance = new Foo();
}
return instance;
}
public int getCounter() {
return counter;
}
public void setCounter(int counter) {
this.counter = counter;
}
}
现在有一个名为 Bar
的 Foo
客户端:
public class Bar {
private Foo foo;
public Bar(Foo foo){
this.foo = foo;
this.foo.setCounter(10);
this.foo.setCounter(20);
}
public int getCounter(){
return foo.getCounter();
}
}
所以 Bar
做了 2 件不寻常的事情 - 1. 在构造函数中调用 Foo
,而不是仅仅使用 Foo.getInstance()
和 2 . 将 Foo
保存为成员,以便“保存”调用 Foo.getInstance()
的样板文件并使用它。当然,我演示的用法是微不足道的。
这对我来说看起来很奇怪和尴尬,更糟糕的是,我根本无法在 Bar
范围内将 Foo
识别为单例。如果我改变某些重要的状态怎么办?但除了代码可读性的原因之外,我不能说这样做不是可选的,而且这种用法似乎最终是有效的。我是对还是错?出于什么原因?传递这个单例并将其保存为成员是否正确?
最佳答案
这看起来确实很主观。如果您认为代码有可能在某些时候不再是单例,或者您认为可能会使用依赖注入(inject)的 Spring 等框架,那么保留对单例的引用会很方便。所以你可以说这是对 future 灵 active 的期待。一般来说,单例会因为与真正的面向对象代码相反而受到批评。
但同时,如果您的应用程序严重依赖单例,并且这是一种非常典型的模式……并且如果您担心由于这种用法,您最终可能会得到单例类的重复实例,那么可以争论此代码与您的应用程序的常见模式和使用期望不匹配,并且它应该遵循预期的准则。
如果不了解更多关于您的应用程序、团队等的信息,很难给出比这更具体的答案。
关于java - 我应该传递一个单例作为函数参数吗,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54561683/