3

Having a larger WinForms application with several classes I currently pass references to several "central" objects around to function calls.

This leads to more method parameters.

Example:

public static class Program
{
    private static MyCentral _central;

    ...
}

...

public class SomeController
{
    public object SomeFunction(MyCentral central) 
    {
        // Do something with the MyCentral instance.
    }
}

Now I'm asking myself whether I should ditch this approach and instead use singletons for those central objects so that everyone can always access these objects and I do not need to pass them around anymore.

Example:

public static class Program
{
    public static MyCentral Central { get; private set; }

    ...
}

...

public class SomeController
{
    public object SomeFunction() 
    {
        // Do something with the Program.Central singleton.
    }
}

My question:

Are there any rules-of-thumb whether the singleton approach or the "passing objects around" approach should be prefered?

0

2 Answers 2

6

The rule of thumb is:

Always pass around, never use the traditional singleton pattern approach.

The problem kind of solves itself if you use a dependency injection framework.

Using public statics will make testing harder, strongly couple your components, and make dependencies between your classes harder to see.

8
  • 1
    Have a look at dependency injection frameworks - it solves exactly this problem in a very clean and elegant way. For .Net, I can recommend Ninject.
    – Wilbert
    Jun 27, 2014 at 9:54
  • 4
    The second rule of thumb is "always take with a pinch of salt any rule of thumb that starts 'never'." However, in this case, I would err on the side of too-strict.
    – pdr
    Jun 27, 2014 at 9:58
  • 1
    Where does this rule come from? In my world where I use an object oriented language, I think that there actually should be singletons. The idea with object oriented development is that you model the classes after the real world. If there is an object that is only one instance and there will only be one instance, it should actually be a singleton. Otherwise you are not using object oriented development in a right way. There are workarounds to fix the issue with "hard to test" when using the singleton pattern. However public statics for the easy of programming should be avoided. Jun 27, 2014 at 12:05
  • 2
    @JohanKarlsson Sure, but you are mixing singleton (object which has only a single instance) with a singleton stored in a global object. Nothing stops you from ever instantiating a singleton class once and then passing it around, and then, if one day you need to mock or stub it for tests you are suddenly able to do it. I personally feel that the main benefit of passing around instances instead of using singletons is that it makes testing not only easier but possible. If you are not doing automated testing or your tests are big enough to not need mocking/stubbing, then the benefit is smaller.
    – Maurycy
    Jun 27, 2014 at 12:17
  • 2
    Singleton (the name) is very loaded because of the infamous pattern associated with it. Yes, we need objects with a single instance. No, we do not need the singleton static/global pattern.
    – Wilbert
    Jun 27, 2014 at 12:20
4

Why not

public static class Program
{
    private static MyCentral _central;

    ...
    var controller = new SomeController(_central);
}

...

public class SomeController
{
    MyCentral _central;
    public SomeController(MyCentral myCentral)
    {
        _central=myCentral;
    }


    public object SomeFunction() 
    {
        // Do something with _central
    }
}

This is called "constructor injection". The central object has only to be passed once to your controller, it can be "mocked out" for testing purposes, and if you decide later that you need to have more than one central object, it won't become a problem.

2
  • 1
    While not using singletons because it makes testing easier gives more immediate gratification, Doc nailed the bigger reason. When all of a sudden you need that 2nd instance, which should never happen, but does. Of course that usually only happens on successful projects because who wants to expand capabilities on applications no one is using. "Developer: We'll only ever use XYZ database so singleton is the obvious choice....some time much later...Manager:We have a potential customer but they want to use ABC database. Developer:That is going to be really, really difficult. NO NEW CUSTOMER."
    – Dunk
    Jun 27, 2014 at 14:13
  • 1
    @Dunk: actually, using dependency injection for a single class is much easier than making a program not depend on a specific database system - there is much more to take care of than to avoid make the db connection a singleton, and such a design does not come without a cost. But I agree fully to the general point behind your comment: using DI to separate a program into independent "building bricks" (or "components") makes it easier in the long run to react to changing requirements.
    – Doc Brown
    Jun 30, 2014 at 6:46

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