1

I'm practicing on writing testable code. One problem I have ran to (researched a lot too) is singleton pattern. It's global state nature makes it unreliable to test because singleton's property changes are kept between the execution of each case.

Even so, singleton is a design pattern that is used to address issues that regards the whole application, a NavigationManager for example.

Here is a simple implementation of a navigation manager class, whose responsability is to keep track of the user's navigation through the app.

For examples I'd like us to use C# or Java.

class NavigationManager {
    private ICollection<INavigable> navigables; // all possible navigables views
    private Stack<INavigable> navigableStack; // the navigation stack
    private INavigable currentNavigable;  // the current view

    private NavigationManager() {
        navigables = new ICollection<INavigable>()
        navigables.Add( // register all posible navigables
    }

    static NavigationManager Instance {
        get {
            if(_instance == null ) { 
                  _instance = new NavigationManager(); 
            }
            return _instance 
        }
    }
    private static NavigationManager _instance;

    void navigateTo(INavigable n) { //.. code to change view
}

It is clear the class should be a singleton so that we can navigate through views with navigateTo(), what's an alternative to singleton to achieve this?

  • Use the mediator pattern to pass events outside the view model – Ewan Jul 4 '15 at 8:18
4

It's not because a class should only have one instance in a particular application that you have to use a singleton pattern. That is the key to solving this.

Simply only instantiating an instance of the class once and then passing it around to other classes needing it still maintains the singleton as a concept - only one instance - but does not have the disadvantage in the testing department and leads to nicer code in general because not everything depends on a singleton. To take this further, if needed, you can even make everything take an interface instead and also get rid of the dependency on a concrete implementation. Which in turn improves testability even more (depending on language and tools used, but most work better with interfaces). Suggested reading: Dependency Inversion, Inversion of Control.

In a small app passing around that instance can be done 'manually' via arguments. In large apps that becomes tedious and that is where Dependency Injection comes into the picture, implemented what is called an 'Inversion of Control' framework. It's abit much to go into detail here so check some tutorials on particular frameworks.

To give you a rough idea of how it solves your problem here is a sample for C# using MEF which I like personally because it uses attributes. First you don't need the static Instance method anymore. Furthermore you make it implement an interface. This results in code like

interface INavigationManager
{
  void NavigateTo( INavigable n );
}

[Export( typeof( INavigationManager) )]
class NavigationManager : INavigationManager
{
  //....current implementation
}

class DoSomeNavigating
{
  private readonly INavigationManager navMan;

  [ImportingConstructor]
  DoSomeNavigating( INavigationManager navMan )
  {
    this.navMan = navMan;
  }

  public void Go( INavigable n )
  {
    navMan.NavigateTo( n );
  }
}

First the testing: no dependency on NavigationManager itself anymore, and suppose you use the Moq mocking framework you'd write tests like

[Test]
void DoSomeNavigating_NavigatesToSomething()
{
  var navMan = new Mock<INavigationManager>();
  var navigable = new Mock<INavigable>();
  navMan.Setup( m => m.NavigateTo( navigable ) );

  new DoSomeNavigating( navMan.Object ).Go( navigable.Object );

  mock.VerifyAll(); //check that navMan.NavigateTo( navigable ) was called
}

When you need DoSomeNavigating in the application itself, you ask MEF to create an instance for you and have it automatically fetch an instance of NavigationManager. As the latter is marked with just Export, MEF knows it should should only create one instance of it so it takes care of the singleton concept for you. Since the first is marked with ImportingConstructor MEF knows it wants an instance of something which implements INavigationManager. Which in this case will be the NavigationManager instance.

var doNav = container.GetExportedValue<DoSomeNavigating>();
  • I was reading the source code of another app that uses MEF, by pure coincidence, and I was wondering if MEF was a DI framewok. Back to business, in conclusion, the standard/most acclaimed way to solve design issues like this is using a DI framework? – Christopher Francisco Jul 4 '15 at 14:56
  • Not using a singleton but instead passing an instance, possibly using an interface instead of a concrete implementation is (afaik) the way to not having to deal with singletons, yes. Whether or not using a framework to help with that is also the way I dare not say. Definitely not always. – stijn Jul 4 '15 at 16:33

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.