Asked  6 Months ago    Answers:  5   Viewed   37 times

Possible Duplicate:
What is so bad about Singletons?

Singleton Design Pattern: Pitfalls

Singleton anti-pattern

I've heard recently that Singleton is an anti-pattern. I know it has to do with the fact making a class singleton is like making that unique instance a global variable, but it's also doing a lot more than that (limiting the number of instances of that object, managing instantiation, etc..).

Why exactly is Singleton considered an anti-pattern? And what are the alternatives?

 Answers

50

To help with answering, here is more about the anti-pattern comment:

it is overused, introduces unnecessary restrictions in situations where a sole instance of a class is not actually required, and introduces global state into an application

From: http://en.wikipedia.org/wiki/Singleton_pattern

For more on this you can look at: https://www.michaelsafyan.com/tech/design/patterns/singleton

Here is a great ending to the blog above:

In short, the singleton pattern makes code more complex, less useful, and a real pain to re-use or test. Eliminating singletons can be tricky, but it’s a worthwhile endeavour.

OK, so, the reason it is an anti-pattern is described well in this paragraph, and, as the author expresses, it tightly couples your code to the singleton.

If you find that you want to use a singleton, you may want to consider your design, but there are times where it is useful.

For example, once I had to write an application that could have at most one database connection, to process thousands of requests. So, a singleton makes sense since I am resource constrained to having only one instance.

But, generally this is used to simplify code, without thinking of the difficulties that will be introduced.

For example, and this applies to static classes also, if you unit test, or have concurrency, then the state of one request will change the state and that may cause problems, as the class calling the instance may be assuming the state is as it expected.

I think the best way to challenge the use is to think of how to handle it if your program is multi-threaded, and a simple way to do that is to unit test it, if you have several tests that run at one time.

If you find that you still need it, then use it, but realize the problems that will be encountered later.

Tuesday, June 1, 2021
 
Terry
answered 6 Months ago
28

Returning this allows you to chain calls and set values. It is very useful for configuring some object (see Fluent interface). You can express very easily what you want (and you can use different return types to achieve what you want).

Wednesday, March 31, 2021
 
Litty
answered 9 Months ago
16

Testing

One reason is that singletons aren't easy to handle with unit tests. You can't control the instantiation and by their very nature may retain state across invocations.

For that reason the principle of dependency injection is popular. Each class is injected (configured) with the classes they need to function (rather than derive via singleton accessors) and so tests can control which dependent class instances to use (and provide mocks if required).

Frameworks such as Spring will control the lifecycle of their objects and often create singletons, but these objects are injected into their dependent objects by the framework. Thus the codebase itself doesn't treat the objects as singletons.

e.g. rather than this (for example)

public class Portfolio {
   private Calculator calc = Calculator.getCalculator();
}

you would inject the calculator:

public class Portfolio {
   public Portfolio(Calculator c) {
      this.calc = c;
   }
}

Thus the Portfolio object doesn't know/care about how many instances of the Calculator exist. Tests can inject a dummy Calculator that make testing easy.

Concurrency

By limiting yourself to one instance of an object, the options for threading are limited. Access to the singleton object may have to be guarded (e.g. via synchronisation). If you can maintain multiple instances of those objects, then you can tailor then number of instances to the threads you have running, and increase the concurrent capabilities of your codebase.

Wednesday, June 2, 2021
 
VieStar
answered 6 Months ago
35

I'd go for the multiple return statements. This makes the code easy to read and understand.

Don't use goto for obvious reasons.

Don't use exceptions because the check you are doing isn't exceptional, it's something you can expect so you should just take that into account. Programming against exceptions is also an anti-pattern.

Saturday, July 17, 2021
 
exxed
answered 5 Months ago
75

Given the following two classes:

class CalculatorBean  
{  
    //getters and setters  
}  

class CalculatorBeanService  
{  
   Number calculate(Number first, Number second);  
    {  
       //do calculation  
    }  
} 

If I understand correctly, Fowler is stating that because your CalculatorBean is just a bunch of getters/setters you don't gain any real value from it and if you port that object to another system it will do nothing. The problem seems that your CalculatorBeanService contains everything that the CalculatorBean should be responsible for. Which is not the best as now the CalculatorBean delegates all of its responsibility to the CalculatorBeanService

Sunday, August 8, 2021
 
Sendy
answered 4 Months ago
Only authorized users can answer the question. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :  
Share