In this note, I will describe my experience and the experience of my colleagues when working with the Singleton pattern (Singleton in foreign literature), when working on various (successful and not so) projects. I will describe why I personally think this pattern cannot be used anywhere, I will also describe what psychological factors in the team affect the integration of this anti-pattern. Dedicated to all fallen and crippled developers who tried to understand why it all started with one of the team members bringing a cute little puppy, easy to handle, not requiring special care and knowledge on caring for it, and ended with the fact that the bred beast took your project hostage, demands more and more man-hours and eats up the human-nerves of users, your money and draws absolutely monstrous figures for assessing the implementation of seemingly simple things.
Wolf in sheep’s clothing by SarahRichterArt
The story takes place in an alternate universe, all coincidences are random…
Pet a cat at home with Cat@Home
Every person sometimes in life has an irresistible desire to pet a cat. Analysts around the world predict that the first startup to create an application for the delivery and rental of cats will become extremely popular, and in the near future will be bought by the company Moogle for trillions of dollars. Soon this happens – a guy from Tyumen creates the application Cat@Home, and soon becomes a trillionaire, the company Moogle gets a new source of income, and millions of stressed people get the opportunity to order a cat to their home for further petting and calming.
Attack of the Clones
A very rich dentist from Murmansk, Alexey Goloborodko, impressed by an article about Cat@Home from Forbes, decides that he also wants to be astronomically rich. To achieve this goal, through his friends, he finds a company from Goldfield – Wakeboard DevPops, which provides software development services, he orders the development of a clone of Cat@Home from them.
Team of Winners
The project is called Fur&Pure, a talented team of 20 developers is assigned; then we focus on a mobile development group of 5 people. Each team member gets their share of the work, armed with agile and scrum, the team completes the development on time (in six months), without bugs, releases the application in the iStore, where 100,000 users rate it at 5, many comments about how wonderful the application is, how wonderful the service is (it is an alternative universe, after all). The cats are ironed, the application is released, everything seems to be going well. However, Moogle is in no hurry to buy a startup for trillions of dollars, because Cat@Home has already appeared not only cats but also dogs.
The dog barks, the caravan moves on
The app owner decides it’s time to add dogs to the app, asks the company for an estimate, and gets about at least six months to add dogs to the app. In fact, the app will be written from scratch again. During this time, Moogle will add snakes, spiders, and guinea pigs to the app, and Fur&Pur will only get dogs.
Why did this happen? The lack of a flexible application architecture is to blame, one of the most common factors being the Singleton design anti-pattern.
What’s wrong?
In order to order a cat to your home, the consumer needs to create an application and send it to the office, where the office will process it and send a courier with the cat, the courier will then receive payment for the service.
One of the programmers decides to create a class “CatApplication” with the necessary fields, and puts this class in the global application space via a singleton. Why does he do this? To save time (a penny saving of half an hour), because it is easier to put the application in general access than to think through the application architecture and use dependency injection. Then the other developers pick up this global object and bind their classes to it. For example, all the screens themselves access the global object “CatApplication” and show the application data. As a result, such a monolithic application is tested and released.
Everything seems fine, but suddenly a customer appears with a requirement to add applications for dogs to the application. The team frantically begins to estimate how many components in the system will be affected by this change. Upon completion of the analysis, it turns out that 60 to 90% of the code needs to be redone to teach the application to accept in the global singleton object not only “ApplicationForCat” but also “ApplicationForDog”. It is useless to estimate the addition of other animals at this stage, at least two can be handled.
How to avoid singleton
First, at the requirements gathering stage, clearly indicate the need to create a flexible, extensible architecture. Second, it is worth conducting an independent examination of the product code on the side, with a mandatory study of weak points. If you are a developer and you like singletons, then I suggest you come to your senses before it is too late, otherwise sleepless nights and burnt nerves are guaranteed. If you are working with a legacy project that has a lot of singletons, then try to get rid of them as quickly as possible, or from the project.
You need to switch from the anti-pattern of singletons-global objects/variables to dependency injection – the simplest design pattern in which all the necessary data is assigned to the class instance at the initialization stage, without any further need to be tied to the global space.
Sources
https://stackoverflow. com/questions/137975/what-is-so-bad-about-singletons
http://misko.hevery.com/2008/08/17/singletons-are-pathological-liars/
https://blog.ndepend.com/singleton-pattern-costs/