简体   繁体   English

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

[英]Java: What's the difference between system property and class variable in singleton class?

I have a singleton class that looks like this我有一个看起来像这样的单例类

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
    }
}

I want to maintain a timestamp for when the list was last processed.我想维护上次处理列表的时间戳。 However I'm trying to decide whether to use a private class variable to record it or create a system variable like System.setProperty("timestamp", System.currentTimeMillis());但是我正在尝试决定是使用私有类变量来记录它还是创建一个系统变量,如System.setProperty("timestamp", System.currentTimeMillis()); and access it.并访问它。 My requirements are that I want to access this value only within the Data class but I am running multiple instances of another class (say DataAccessor) that uses Data.process .我的要求是我只想在 Data 类中访问这个值,但我正在运行另一个使用Data.process的类(比如 DataAccessor)的多个实例。 I want to get the latest value of timestamp irrespective of which DataAccessor instance calls Data.process but I am not sure if there are any differences between storing variables through system property vs local variables in a singleton class.无论哪个 DataAccessor 实例调用Data.process ,我都想获得时间戳的最新值,但我不确定通过系统属性存储变量与单例类中的局部变量之间是否存在任何差异。

It doesn't matter, and this is, as far as code style is concerned, deplorable already, so it seems a bit silly to worry about it.没关系,就代码风格而言,这已经很糟糕了,所以担心它似乎有点愚蠢。

That's not how you make a singleton这不是你制作单身人士的方式

It won't actually be a singleton if you call getInstance() from multiple threads.如果您从多个线程调用getInstance() ,它实际上不会是单例。 Just write:写吧:

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

  public static Data getInstance() {
    return data;
  }
}

What you're doing ('lazily' make the singleton instance) is double useless:你在做什么('懒惰'制作单例实例)是双重无用的:

  • It's only useful in the first place if your code 'touches' the type ( Data ), but doesn't call getInstance() .仅当您的代码“触及”类型( Data )但不调用getInstance()时,它首先才有用。 This is rare for all singletons.这对于所有单身人士来说都是罕见的。
  • It's only useful if the cost of creating the instance is high.只有在创建实例的成本很高时才有用。 It clearly is not, here.显然不是,这里。

That's not how you name classes这不是你命名课程的方式

Data is not very descriptive. Data不是很具有描述性。 It's almost clichéd in how non-descriptive it is.它的非描述性几乎是陈词滥调。 More generally a class represents an actor of sorts - it's supposed to be a noun.更一般地说,一个类代表某种演员——它应该是一个名词。 It should be LogStorage for example, if the point of this thing is to store logs, or even better AtmLogStorage if it's specifically representing the printroll of an ATM that logs cash it emitted.例如,它应该是LogStorage ,如果这个东西的目的是存储日志,或者如果它专门表示记录它发出的现金的 ATM 的打印卷,则更好的AtmLogStorage Be specific.请明确点。

This isn't a good use of a singleton这不是一个很好的使用单例

It's feasible to imagine a system that is running 2 separated concepts that both need the same logging functionality.可以想象一个系统运行 2 个独立的概念,这两个概念都需要相同的日志记录功能。

Stateless singletons (example: java's Collections or Files classes - they don't have fields or otherwise any state that you can modify) are always fine.无状态单例(例如:java 的CollectionsFiles类——它们没有字段或任何可以修改的状态)总是可以的。 Stateful singletons, like this one, usually aren't.有状态的单例,比如这个,通常不是。 Use injection frameworks if you must.如果必须,请使用注入框架。

Singletons are hard to test单例很难测试

When writing tests you tend to want to set up dummy versions or otherwise configure some object differently than you would at normal runtime, and you usually want to be able to repeatedly create things (to isolate tests) that, during normal runtime, is only created once.在编写测试时,您倾向于设置虚拟版本或以其他方式配置某些对象,而不是在正常运行时,并且您通常希望能够重复创建在正常运行时仅创建的东西(以隔离测试)一次。 Singletons and 'I wrote a unit test' do not like each other.单身人士和“我写了一个单元测试”彼此不喜欢。

So, what do you do?所以你会怎么做?

Make the field - and fix everything else if you can.制作场地 - 如果可以的话,修复所有其他问题。 At least with the field you can later refactor your code and make it possible to have more than one Data (hopefully you renamed it), even if just for testing purposes.至少使用该字段,您可以稍后重构您的代码并使其可以拥有多个Data (希望您将其重命名),即使只是为了测试目的。 system properties:系统属性:

  • Cannot be controlled (any code can read and write them - you have no control over it).无法控制(任何代码都可以读取和写入它们 - 你无法控制它)。
  • Are invisible state, in that most java apps do not use the sysproperty store to write data.是不可见状态,因为大多数 java 应用程序不使用 sysproperty 存储来写入数据。 Hence most tools aren't written to deal with it;因此,大多数工具都不是为了处理它而编写的。 debug tools can be set to breakpoint if someone changes a field, it's much harder to breakpoint them upon some code changing a sysproperty - requires having the java core sourcecode and setting a conditional breakpoint on the setProperty method which comes in various flavours, oof.如果有人更改了字段,则可以将调试工具设置为断点,在某些代码更改 sysproperty 时对它们进行断点要困难得多 - 需要拥有 java 核心源代码并在setProperty方法上设置条件断点,该方法有各种风格,oof。
  • Are 'singleton' and cannot be refactored away from it, whereas a field is on its own not singleton in the slightest (the fact that there's only ever one instance of the class with this field makes it a singleton, but change that aspect and your field ceases to be one. That's good).是“单例”并且不能从它那里重构,而一个字段本身就不是单例(事实上只有一个类的实例具有该字段,这使它成为一个单例,但是改变这方面和你的字段不再是一个。这很好)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 类包装器和Java,以及Objective-C中的单例之间有什么区别? - What is the difference between a class wrapper and Java, and a singleton in Objective-C? 枚举和单例类有什么区别 - What is the difference between Enum and a singleton class System属性和环境变量之间的区别是什么 - What's the difference between a System property and environment variable “ int变量= 0;”和“ int变量”之间有什么区别? 变量= 0;”在Java类中? - What's the difference between “int variable = 0;” and “int variable; variable = 0;” in Java class? System.getProperty("java.class.path") 和 getClassLoader.getURLs() 有什么区别? - What's the difference between System.getProperty("java.class.path") and getClassLoader.getURLs()? 单例类中的私有静态变量和私有实例变量有什么区别? - What is the difference between private static variable and private instance variable in a singleton class? 使用 singleton class 和 class 与 ZA81259CEF8E959C624DF1D456E5D2 方法有什么区别? - What is difference between using singleton class and class with static methods? 类变量和构造函数中的参数有什么区别? - What's the difference between a class variable and a parameter in a constructor? 具有同步功能的单例类和静态同步功能之间有什么区别 - What's the difference between a singleton Class with synchronized function and a static synchronized function StringTokenizer和java.util.Scanner类之间的区别是什么 - What's the Difference between StringTokenizer and java.util.Scanner Class
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM