Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Possible Valid Use of a Singleton?

I've got to the point in my design, where I am seriously considering a singleton.

As we all know, the "common" argument is "Never do it! It's terrible!", as if we'd littered our code with a bunch of goto statements.

ServiceStack is a wonderful framework. Myself and my team are sold on it, and we have a complicated web-service based infrastructure to implement. I have been encouraging an asynchronous design, and where possible - using SendAsync on the service-stack clients.

Given we have all these different systems doing different things, it occurred to me I'd like to have a common logger, (A web service in itself actually, with a fall-back to a local text file if the web service is not available - e.g. some demons are stalking the building). Whilst I am a big fan of Dependency Injection, it doesn't seem clean (at least, to me) to be passing a reference to a "use this logger client" to every single asynchronous request.

Given that ServiceStack's failure signature is a Func<TRESPONSE, Exception> (and I have no fault with this), I am not even sure that if the enclosing method that made the call in the first place would have a valid handle.

However, if we had a singleton logger at this point, it doesn't matter where we are in the world, what thread we are on, and what part of a myriad of anonymous functions we are in.

Is this an accepted valid case, or is it a non-argument - down with singletons?

like image 855
Moo-Juice Avatar asked Apr 24 '13 20:04

Moo-Juice


People also ask

What can singleton be used for?

Singleton pattern is used for logging, drivers objects, caching and thread pool. Singleton design pattern is also used in other design patterns like Abstract Factory, Builder, Prototype, Facade etc. Singleton design pattern is used in core java classes also, for example java.

What is singleton and where is it used?

It is used where only a single instance of a class is required to control the action throughout the execution. A singleton class shouldn't have multiple instances in any case and at any cost. Singleton classes are used for logging, driver objects, caching and thread pool, database connections.

What is the use of singleton class in Java?

A Singleton class in Java allows only one instance to be created and provides global access to all other classes through this single object or instance. Similar to the static fields, The instance fields(if any) of a class will occur only for a single time.

What problem does singleton solve?

The singleton design pattern solves problems by allowing it to: Ensure that a class only has one instance. Easily access the sole instance of a class. Control its instantiation.


2 Answers

Logging is one of the areas which makes sense to be a singleton, it should never have any side-effects to your code and you will almost always want the same logger to be used globally. The primary thing you should be concerned with when using Singletons is ThreadSafety, which in the case of most Loggers, they're ThreadSafe by default.

ServiceStack's Logging API allows you to both provide a substitutable Logging implementation by configuring it globally on App_Start with:

LogManager.LogFactory = new Log4NetFactory(configureLog4Net:true);

After this point every class now has access to Log4Net's logger defined in the Factory above:

class Any
{
    static ILog log = LogManager.GetLogger(typeof(Any));
}

In all Test projects I prefer everything to be logged to the Console, so I just need to set it once with:

LogManager.LogFactory = new ConsoleLogFactory();

By default ServiceStack.Logging, logs to a benign NullLogger which ignores each log entry.

like image 147
mythz Avatar answered Oct 03 '22 18:10

mythz


There's only one problem with classic implementation of a singleton - it is easily accessible, and provokes direct use, which leads to strong coupling, god objects, etc.

under classic implementation I mean this:

class Singleton
{
   public static readonly Singleton Instance = new Singleton();
   private Singleton(){}
   public void Foo(){}
   public void Bar(){}
}

If you use singleton only in terms of an object lifecycle strategy, and let IoC framework manage this for you, maintaining loose coupling - there is nothing wrong with having 'just one' instance of a class for entire lifetime of application, as long as you make sure it is thread-safe.

like image 40
Alexander Avatar answered Oct 03 '22 17:10

Alexander