Validation and subclasses of Singletons

I saw this when using picocontainer. They say you need to avoid single people. because the Singleton pattern makes it almost impossible to validate a class (and possibly all other classes that depend on it). It is very difficult to subclass or to create a layout for the Singleton class.

But if you absolutely need it, is there a way around the testing problem and subclass?

+6
source share
3 answers

What makes singletons difficult to test is the code that provides them with a singleton (which means the public static MySingleton getInstance() {...} template). Using a container with inverse control like Picocontainer or Guice or Spring fixes this problem with the object, so now:

  • It can be created, and collaborators are connected to it in tests without problems.

  • The code that calls the singleton doesn't have to know which class it is looking for (it needed to know if it needed to call the static method).

I interpret the advice on the picocontainer website as similar to this one. What they tell you allows our container to manage the scope of your components for you, do not enter code that provides scope for them.

+5
source

If you must have singlets:

  • An interface that describes each singleton.
  • Access your singles from the global / singleton ServiceLocator
  • Switching instances registered with ServiceLocator during testing

Example:

 interface IBankApi { public void MakeDeposity(int accountNumber, int dollarAmount); // ... } public class RealBankApi : IBankApi { ... } // startup code serviceLocator.Register<IBankApi>(new RealBankApi()); // code using the API serviceLocator.Resolve<IBankApi>().MakeDeposit(...); // test code setup class FakeBankApi : IBankApi { ... } serviceLocator.Register<IBankApi>(new FakeBankApi()); 
+1
source

The use of IOC (control inversion), rather than single, initiated upon first use, is beneficial for other reasons.

Syntactic initialization can suffer (famously) from multi-threaded problems when two threads try to access it for the first time at the same time. Subsequent access is likely to be correctly synchronized, but the first one is much more difficult to do.

Another huge advantage that I have found in using IOC is when an initialization error can occur. You do not want this to happen during the "first use", you want to know about this failure at an early stage, and, of course, it is easier to deal with this error.

Finally, in terms of testing, IOC provides an ideal model for isolating components, replacing them as needed, and combining various combinations more flexibly, thereby providing the perfect binding for unit testing and integration testing as a good rollback mechanism without actually returning any code at all.

The common reason singletones are used so often is not unity, but globality. If your project is managed correctly, you have one global object to which all the others are โ€œregisteredโ€ (thus, your IOC model freezes) and are available worldwide, although it is still configurable.

+1
source

Source: https://habr.com/ru/post/894287/


All Articles