Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Force singleton pattern in subclasses

I would like to force subclasses to implement the singleton pattern.

I originally thought of having an abstract static property in the parent class, but upon closer though, that didn't make sense (abstract requires and instance).

Next, I thought of having an interface with a static property, but that also doesn't make sense (interfaces also require an instance).

Is this something which is possible, or should I give up this train of thought and implement an abstract factory?

like image 429
Ben S Avatar asked Feb 25 '09 20:02

Ben S


People also ask

Can a singleton class have subclasses?

Subclassing a Singleton class may be tricky, since a subclass object cannot be created unless the superclass object has not yet been created. You may want to extend the Singleton class to allow not just a single instance, but some small fixed maximum number of instances.

What is the best way to subclass Singleton?

I would argue the most common way to implement a singleton is to use an enum with one instance. That might be a "better" way but definitely not the most common way. In all the projects I have worked on, Singletons are implemented as I have shown above.

Can a Singleton inherit from another class?

Unlike static classes, Singleton classes can be inherited, can have base class, can be serialized and can implement interfaces. You can implement Dispose method in your Singleton class. So, static classes are much less flexible compared to Singleton classes.


2 Answers

Please reconsider. You do NOT want to use singletons here. You are making some functionality available to users who derive from your class. That's fine. But you're also dictating one specific way in which it must always be used, and for absolutely no reason. That is not good.

It may make sense to only instantiate one object of this class the majority of the time, but in that case, simply just instantiate the object once. It's not like you're very likely to accidentally instantiate a dozen objects without noticing. Moreover, how can you tell that having two instances will NEVER be useful? I can think of several cases even now.

Unit testing: You might want each test to instantiate this object, and tear it down again afterwards. And since most people have more than one unit test, you'll need to instantiate it more than once.

Or you might at some point decide to have multiple identical/similar levels in your game, which means creating multiple instances.

A singleton gives you two things:

  • A guarantee that no more than one instance of the object will ever be instantiated, and
  • Global access to that instance

If you don't need both these things, there are better alternatives. You certainly don't need global access. (globals are bad, and usually a symptom of bad design, especially in mutable data such as your game state)

But you don't need a guarantee that no more than one instances will ever be instantiated either. Is it the end of the world if I instantiate the object twice? Will the application crash? If so, you need that guarantee. But in your case, nothing bad will happen. The person instantiating the object simply uses more memory than necessary. But he might have a reason.

Simply put in the class documentation that this is a very big and expensive class, and you shouldn't instantiate it more often than necessary. Problem solved. You don't remove flexibility that might turn out to be useful later on, you don't grant global access to data for no reason. Because you can control who can see the object, you don't need to drown it in locks that will become a bottleneck in multithreaded applications. You don't have hidden dependencies scattered throughout your code, making it harder to test and harder to reuse.

like image 199
jalf Avatar answered Oct 23 '22 21:10

jalf


Try using an IOC container. Most good IOC containers enable the use of the singleton pattern without having to implement it yourself (ie: spring framework) - I like this better than forcing a static GetInstance() method.

Besides, it's not really possible in java, it would work in C++ with templates though.

like image 25
Brian Dilley Avatar answered Oct 23 '22 21:10

Brian Dilley