Singleton design pattern is on the most famous and used design patterns. It's also a source of endless debates between software engineers! In this session, we discuss the perks and perils of the singleton design patters.
3. Motivation
You have that one, and exactly one object:
● Database connection
● Hardware interface
● …
and you have to make sure all parts of the application use
that one and only object
4. Solution
Head up to that class, and:
● Restrict the class to create only one object
● Provide global access to it
Ref: [1]
11. Benefits
● State shared globally as required
● Global access; No complications to object access
● The object handles its own creation logic
● Hide details of the Singleton
● Can be used to implement some other patterns as well
○ Abstract Factory, Builder, Prototype …
13. Singleton as an anti-pattern
Singleton is popular because:
● It was included in GoF Design Patterns
● It’s easy; the easiest in the book
People started a rebellion:
● Any design pattern can be abused, except for Singleton
● Valid motive, but ruins everything with its two steps
Ref: [3, 10]
14. Glorified Global Variables
Have a bug? Now go over all those files for a clue!
Mutable
state
1
This one
caused the
bug
2
This one
found it
Ref: [4]
15. Glorified Global Variables
When some code uses a global variable, it’s harder to
reason about it
Mutable
state
1
To know what this
object / function is
doing
2
You also
need to
understand
what this is
doing
Ref: [4]
16. Lifecycle
The Singleton controls its own creation and lifecycle
● Violation of SRP:
○ Connecting to database is a responsibility
○ Creating, opening and closing the connection are other
responsibilities
● Resetting the state is harder and more error-prone
than creating a new object
Ref: [3, 5]
17. Lifecycle
● Now you have to make all
Singletons reset to initial state
● You have to wait to reset
properly
○ Sync data
○ Clear cache
18. Lifecycle
● The user’s signed-in session is shorter than the
application’s lifecycle.
● A global state, if necessary, should only handle states
that last for the entire application’s complete lifecycle
Ref: [5]
19. Hiding Dependencies
● You don’t know what that Singleton needs
○ Singleton.getInstance() doesn’t explain much
Data List Singleton
What you see
Data List Singleton
What it actually is
Connection Authenticator
User
Ref: [3]
20. Hiding Dependencies - Example
● Only works when you run as
part of the suite.
● When run in isolation,
throws
NullPointerException.
Ref: [3]
21. Hiding Dependencies - Example
● You ask a senior, and he tells
you that CreditCardProcessor
needs to be handled first
● Still, it throws an exception
Ref: [3]
22. Hiding Dependencies - Example
● You ask more. Now you know
that both Database and
OfflineQueue need to be
initialized first
● The code worked!
● Now your bank account only
has $12.5 because this code
charged you for $100
Must be done
in the same
order!
Ref: [3]
23. ● The code is not stable, if Database gets modified,
other classes may fail
○ Because you don’t know what depends on Database and how
● The code is not flexible, anything that depends on a
Singleton is hard wired to that Singleton
● You can’t unit test a class without the Singleton
initialized
● You can’t use mock objects for testing
Hiding Dependencies
Ref: [3]
24. Encourage Coupling
● Since it’s global, any class anywhere can get it easily
● If the developer is thinking hard how to get it in that
class, he would think if that class should get it
Coupling between SomeTransaction
and MySQLConnection
Ref: [4]
25. Encourage Coupling
● Now, you need to use a NoSQL database along with the
SQL one
● SomeTransaction should switch to NoSQL database
SomeTransaction
MongoDBConnection
MySQLConnectionTightly coupled
Remove the coupling
between
SomeTransaction and
MySQLConnection first
26. Limiting Instantiation
Are you really sure you won’t need another object of that
Singleton class?
nobacks.com
SingletonScreen
We only need
one object for
that one screen
nobacks.com
So what happens when I plug
that screen to the laptop?
27. Big deal!
I don’t care if they’re bad or not.
I only use one or two Singletons,
what’s going to happen anyway?
Source
28. That’s the real problem!
This one or two Singletons are strangling all or most of
classes
○ Many classes are tightly coupled to it
○ Many classes can’t be tested properly
○ Change something in that Singleton and all other classes need
to be changed as well
29. The Root of the Problem
This part is
very
legitimate!
This is
not
Ref: [9]
30. Solution
● Pass it a.k.a “Inject it!”
● Get it from somewhere already global
○ That place is responsible for creating it and managing its
lifecycle
○ There are some evils that we can only reduce, but can never
eliminate, like global state
Ref: [7]
33. Example
● We’re sure that only one object is being used
● Dependencies are declared
● Dependencies are passed
● Each class is testable and mockable
● “Creation” is the factory’s responsibility
● If you ever need to have a new database, you don’t
have to modify available classes
Ref: [7]
34. Immutable State Singletons
Immutable state Singletons, enums in Java, objects in
Scala, … are okay
But still, be aware of coupling, limiting classes from
inheritance, hiding dependencies …
Ref: [9]
35. References
1. c2.com: Singleton
2. Wikipedia
3. SO: What's so bad about singletons
4. gameprogrammingpatterns.com
5. Avoiding Singleton Abuse
6. programmers.stackexchange: So singletons are bad then what
7. Singletons are pathological liars
8. Where have all the singletons gone
9. Root cause of singletons
10. Singletons considered stupid