user1899020
user1899020

Reputation: 13575

How to not use a singleton?

According to the article, it is suggested to not use a singleton. However, what is the alternative or better way? For example, in my GUI, I have a log window. After an operation, no matter where it is, I can easily record some information in the log window if a singleton is used. The singleton provides a shortcut, although via a global route. If not using singleton, any good way to do it? Note the operations may scatter anywhere. Thanks a lot!

Upvotes: 2

Views: 202

Answers (2)

Jonathan Wakely
Jonathan Wakely

Reputation: 171453

There are several common misunderstandings about Singleton.

The first is that it has any redeeming features and is useful. Wrong. It's crap.

The second misunderstanding is that it means "only have one object". No. It means "enforce the rule that there can only be one object." That's not the same thing.

The Singleton pattern in the Gang of Four Design Patterns book is a "Creational Pattern", because it's role is related to how an object is created. The so-called pattern's purpose is to provide a single, global instance of an object and prevent other instances being created. e.g. make the constructor private and provide a single static function that is allowed to create one instance only. (The fact it has two responsibilities in one type should be a clue it is broken, it violates the single responsibility principle.)

If you must have a single global instance, then (although that might be a symptom of poor design) you can do that quite simply by just creating one. Then you don't need the "enforce the rule there can only be one" property, so you don't need the Singleton "pattern".

Too many people say "it's a Singleton" when they mean "there's only one of it", which is not the same as saying "I have used the language rules to guarantee there can only be one of it".

Or they say "I've got a Singleton" as though that justifies having a global variable. Giving it a fancy name does not excuse crap design.

If you need one instance, create one instance. Don't create more of them. Bingo, you have one instance. Easy. If you can't control how other bits of the program access that instance then your program is already broken. Fix the code. Stop relying on a single instance of the type. Preventing other instances being created doesn't solve your design problem, it just makes it worse.

This is the Just Create One pattern.

If lots of code needs access to that object then pass it to the code (via constructors or function arguments) so the dependencies are explicit. This is the Parameterize from Above pattern.

For a logging module, the code that wants to log should not care that it's logging to a "Singleton" (i.e. a type that cannot have more than one instance,) it should either log to the logger it's passed, or it should log via a global function or object which doesn't need to be a "Singleton" it can just be a global that there is only one of. Do you write code to enforce the rule there is only one std::cout and call std::cout::instance() or do you just accept it's a global and use it? Do you call printf::instance()("%s", ...) or just printf and let the implementer of printf worry about how it works?

Upvotes: 2

Tom Kerr
Tom Kerr

Reputation: 10730

Do the simplest thing that could possibly work. In my experience, the simplest way to do logging is to use free functions.

void logError(const std::string& message);
void logWarning(const std::string& message);
void logInfo(const std::string& message);

Maybe the implementation is just a global, maybe its not. It doesn't matter how you implement it. It only matters that they don't write different code based on how it is implemented. Focus on the interface that is exposed.

IMHO, Singletons are bad because they are hard to change later. Not because of the way they are implemented, but because they tend towards interfaces that only allow for there to be a singleton behind it. That is hard to change. When change is difficult, then it costs a lot to maintain.

Upvotes: 3

Related Questions