Things that should be designed as singletons

  • Thread starter Silicon Waffle
  • Start date
In summary, a singleton is a class that is designed to protect data which must not be duplicated. It can enforce that by procedures.f
  • #1
162
203
I find that any entities that act as a shared resource tend to be designed as a singleton.
My questions and answers are
Q: Can I just expose that object with simple static properties and static methods but without making it a singleton i.e its constructor is still public ?

A: Yes, but I am going to lose its rigidity of use and would probably be error-prone to threading.

Q: Can I apply multi-threading to eliminate read-write accesses to the shared object
properties, which I won't need the singleton design then ?

A: Given a web based application that millions of end-users will send back and forth their requests all the time, what do you think the probability that your likely "multi-threaded" design won't cause any problems would be instead of applying a well known pattern ?

I can't think up anymore questions and answers :nb) :DD. But I would like to split hairs about this. Please offer some insights and constructive guidance, I am appreciative of your inputs. :w
 
  • #2
I think using a static class to do a singleton limits your design flexibility.

I've seen people use a factory class to create and return the singleton object and then later on get changed to manage a pool of objects.

Also using a static class means you have to use the class name each time you refer to the object as opposed to a variable name whose datatype can be changed without refactoring your code.

As an example:
Code:
MyPrinter.print("hello");    // MyPrinter would be used throughout you code

vs

Code:
CheapColorPrinter myPrinter = PrinterFactory.getCheapColorPrinter();

myPrinter.print("hello");

and later on you change it to
Code:
FancyColorPrinter myPrinter = PrinterFactory.getFancyColorPrinter();
or better yet you define an interface ColorPrinter that CheapColorPrinter and FancyColorPrinter use
Code:
ColorPrinter myPrinter = PrinterFactory.getAvailableColorPrinter(); // gets cheap one or fnacy one based on availability...

With respect to being thread use, you could easily design it to be thread-safe so that only one thread at a time could use it but that means under heavy use you've introduced a bottleneck in your code.

This happens in web application code from time to time limited resource causes a bottleneck limiting the number of sessions you can have usually database connections.
 
Last edited:
  • Like
Likes Silicon Waffle
  • #3
Can I apply multi-threading to eliminate read-write accesses to the shared object
properties, which I won't need the singleton design then ?

With this, you have stumbled upon a big design issue, that has been debated literally for decades. Of course, you can do almost anything; but should you?

I wrote telecom software for many years at Bell Labs, and it was impossible not to become involved in design trade-offs, because performance was very important in that application, but also reliability was just as important. A telephone switch has a certain configuration, and commands to reconfigure it come from all over the place, all any time, so the switch must have a strategy for handling multiple input commands, some of which may contradict each other. In the United State and most all of North America, switching systems evolved to used command queues to handle this. That is, commands could arrive from anywhere, anytime, and they would go into a queue and be executed in the order of their arrival--pretty much no matter what (i.e., even if a subsequent command tromped on an earlier command). There was still only one switch (i.e., "the data"), but possibly many users. (Incidentally, this is true of user interface windows, generally).

Then at some point, AT&T (whom I worked for) bought Phillips (I think) in the Netherlands. There was a mightly push to unify AT&T's software with theirs, and I was involved. Turns out, their switching systems (and most in Europe) locked the whole switch. Only one user at a time. It was thus not possible to do inconsistent things, but it wasn't fast. And the software designers of both companies, plus all the existing code, was so entrenched that it proved impossible financially to unify them, despite every political will to do so.

A singleton is typically used to model data that must not be duplicated. You can use a non-static object to do that, as long as everyone understands and complies with not duplicating the data, but a singleton class actually enforces that. The only singleton object I ever used was for persisting data to disk. Basically, the purpose of a singleton is to enforce protection for data which must never be duplicated. You can also enforce that by procedures--as long as, years later, some programmer doesn't accidentally forget about the rule.
 
  • Like
Likes Silicon Waffle
  • #4
For your threading the decision here is to structure the data correctly so that the use and desire for access amongst competing threads/processes is done as to not create a bottle neck (or at least limit it).

This little detail can help you explain why data structures for various things are difficult and also why you have a lot of redundancy in your data (you typically don't just have a single reduced copy of the data - you have all kinds of structures that organize the data effectively so that execution runs faster under the given requirements for said application).

The semaphore object for multi-threading can be implemented in so many ways. You could implement it at the object level (i.e. a process locks the entire object, it's elements, its functions, its interfaces, and so on), at element level (locks a single element), or function level (locks a function) or any combination thereof. What matters is how you do it based on what will be executed and what you design your system for.

For the singleton you have to decide if it really is something that is for lack of a better term - set in stone. You can use namespaces if you want your singleton objects to be done in a way as to not cause confusion amongst other variables with similar names and/or types. Also remember that the point of not having a constructor made public is so that no-one can create the object (and also destroy the object). It means that you can make sure that things run the way they are meant to for this scenario. Some examples of things like this would be a memory management system where you don't want anyone to create a new instance and instead want the application to do everything when it comes to construction and deconstruction - and you simply use the singleton as a means of performing tasks through function calls.
 
  • #5
Also using a static class means you have to use the class name each time you refer to the object as opposed to a variable name whose datatype can be changed without refactoring your code.
Code:
MyPrinter.print("hello");    // MyPrinter would be used throughout you code
In Java, you can import static methods from another class so that it isn't necessary to do that.
Java:
import static MyPrinter.print;
// Or, import all of the static methods in the MyPrinter class
// import static MyPrinter.*;

public static someMethod() {
    print("hello);
}
 
  • #6
Q: Can I apply multi-threading to eliminate read-write accesses to the shared object
properties, which I won't need the singleton design then ?

A: Given a web based application that millions of end-users will send back and forth their requests all the time, what do you think the probability that your likely "multi-threaded" design won't cause any problems would be instead of applying a well known pattern ?
My first thought is that if you have a shared object that every user can modify, you're building it wrong.
 

Suggested for: Things that should be designed as singletons

Back
Top