Java:单例类中的系统属性和类变量有什么区别?



我有一个看起来像的singleton类

public class Data {
private static Data data;
private List<String> list;

private Data() {
list = new ArrayList<>();
}

public static Data getInstance() {
if (data == null) {
data = new Data();
}
return data;
}
public void process() {
//check timestamp value
//process values from list
}
}

我想保留上次处理列表的时间戳。然而,我正在决定是使用私有类变量来记录它,还是创建一个像System.setProperty("timestamp", System.currentTimeMillis());这样的系统变量并访问它。我的要求是,我只想在Data类中访问这个值,但我正在运行另一个使用Data.process的类(比如DataAccessor)的多个实例。无论哪个DataAccessor实例调用Data.process,我都想获得时间戳的最新值,但我不确定通过系统属性存储变量与在singleton类中存储局部变量之间是否存在任何差异。

这没关系,就代码风格而言,这已经很糟糕了,所以担心它似乎有点傻。

这不是你做单身汉的方式

如果您从多个线程调用getInstance(),那么它实际上不会是一个单例。只需写:

public class Data {
private static final Data data = new Data();
public static Data getInstance() {
return data;
}
}

您所做的("随意"创建单例实例)是双重无用的:

  • 只有当您的代码"触及"了类型(Data),但没有调用getInstance()时,它才是有用的。这对所有单身人士来说都是罕见的
  • 只有当创建实例的成本很高时,它才有用。这里显然不是

这不是命名类的方式

Data的描述性不强。它的非描述性几乎是陈词滥调。更普遍地说,一个类代表某种演员——它应该是一个名词。例如,如果这件事的目的是存储日志,那么它应该是LogStorage,如果它专门代表记录其发放现金的ATM的打印卷,那么它甚至应该是更好的AtmLogStorage。具体一点。

这不是对singleton的好使用

设想一个系统运行两个独立的概念是可行的,这两个概念都需要相同的日志记录功能。

无状态的singleton(例如:java的CollectionsFiles类——它们没有字段或任何可以修改的状态)总是可以的。像这样有状态的单身人士通常不会。如果必须,请使用注入框架。

单身汉很难测试

在编写测试时,您往往希望设置伪版本或以其他方式以与正常运行时不同的方式配置某些对象,并且您通常希望能够重复创建在正常运行时只创建一次的东西(隔离测试)。辛格尔顿和"我写了一个单元测试"互不喜欢。

那么,你是做什么的

制作场地——如果可以的话,修复其他一切。至少有了这个字段,您以后可以重构代码,并使多个Data成为可能(希望您将其重命名),即使只是出于测试目的。系统属性:

  • 无法控制(任何代码都可以读取和写入它们-您无法控制它)
  • 是不可见状态,因为大多数java应用程序不使用sysproperty存储来写入数据。因此,大多数工具并不是为了处理它而编写的;调试工具可以设置为断点。如果有人更改了字段,那么在某些代码更改系统属性时就很难对其进行断点设置。这需要具有java核心源代码,并在setProperty方法上设置条件断点,该方法有多种风格,oof
  • 是"singleton",不能从中重构,而字段本身就不是singleton(该类只有一个实例具有该字段,这一事实使它成为singleton,但更改该方面,字段就不再是singleton了。这很好)

最新更新