سؤال

It was already asked what's the difference between singleton and static class. However, knowing the difference, I still feel confused every time I need to chose.

So for myself I defined two different cases - I'm using singletones mainly for POJO classes(in java) if there should be only one instance of this class(which is very rarely) and static classes for all service classes(which occur very often).

For example, in my application I need to store messages(I have a serializable class Message), write them into a file, read from a file and access during the runtime. I don't see any reason to use singleton here, static class is just okay. The only static class is MessageStorage which has 3 functions - read, write and getMessages and also one static private arraylist of messages.

Is this approach reasonable and if not, what's its problem?

هل كانت مفيدة؟

المحلول

The two main reasons for using a "singleton" in Java are:

1) So some storage can be associated with an otherwise "static" class.

2) Where you may have multiple "singletons" for different subclasses (or interface implementations) of a given service, and the singleton is passed as a way of identifying which specific service to employ.

Of course, instead of #1 you can use static fields of a "static" class to contain the data, but it's often more convenient (and, in many cases, more efficient) to have a single instance of the subject class to contain the data, vs multiple static members which are instances of other classes.

And, re #2, there are a number of cases in the JDK of a single class implementing, in effect, multiple "singletons", in the guise of defining "constants". (Eg, java.awt.font.TextAttribute.)

In general, the motivation to have singletons is less in Java than in C-based languages, since Java does implement true class-associated (and class-protected) static data, vs the vaguely disguised (if disguised at all) global statics used in the C languages, and so one can simply have multiple static fields in a class vs the need to have a "central" object to contain the fields in the C languages.

نصائح أخرى

The ideal design :-)

  • MessageStore should be an interface
  • MessageStoreFactory should be a singleton with a getMessageStore() method (if getMessageStore() returns the same message store every time, that is not a problem, and you have your singleton).
  • you can then have multiple MessageStore implementations, such as FileMessageStore, JDBCMessageStore, SubversionMessageStore, etc...
  • Most importantly, you can have MockMessageStore, to mock out message stores and be able to test components which depend on the message store independently of the message store (and isolate any failure). For example, if you are testing MessageView and get an error, you can be sure the error is in MessageView and not in your static MessageStore, given MockMessageStore is correct.

That's what the cool kids are doing now days, anyway... and dependency injection rather than a factory, but one step at a time...

The thing to really understand here is that there are different groups of memory for c#/java.

All of your classes will be loaded into a section of memory called class loader memory. If you make something that is static, it remains there in class loader memory. It can be used from there, but only can have the 1 instance. There is no garbage collector for class loader memory, everything stays there for the life of the application.

Creating an instance of a class whether it be singleton or not means that a memory copy is done, copying your class from class loader memory and copying it to the area where instances are stored. Instances can be garbage collected.

The actual decision point between the option of singleton and static class is:

1) Do you want inheritance, or an interface for your class (if so you want singleton)
2) Does it make sense to force your class to have a lifecycle that is the same as your applications (ie you would have to manually clear the class or write a method to do it which unessasarily increases code, hence decreasing maintainability). (if it doesn't then you want singleton)
3) Does your Application require scalability, and potential for change. Singleton is often considered an anti-pattern nowadays, IF implemented via a static property. The reason for this is that you invest in infrastructure like exposing a static instance property on your class which might be entirely not what you want in the future because your single window application could suddenly become multi window and you need to rewrite code. (rewriting code is indicative of bad design, especially if its core infrastructure).

As a general rule of thumb, I would recommend the following:

  • Any class where there are class wide variables, that should be a singleton (because of the need to potentially scale it out).
  • Any class where each method stands on its own, should be static.
مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top