Resource Management

Started by
21 comments, last by Satharis 9 years, 1 month ago


So do you claim that singleton patterns are bad habit? I've seen them used many times while viewing engines' source codes.

Other's have already addressed it, and I don't want this thread to descend into yet another long discussion of Singleton's pitfalls like so many others have. But since you asked me, I'll defend my position briefly.

The single worst thing that the Singleton pattern does, IMO, is that it allows you to feel good about outright ignoring important and often multitudinous dependencies that really ought to be thought about carefully, or at the very least ought to be obvious. The globalness and alwaysness of Singleton allows this to happen, and its facade of OOP-ness fools you into thinking that this state of affairs is A-Okay. Furthermore, the singleness of Singleton allows you to make the dangerous assumption that there will only ever be one, and so your typical singleton object never stops to consider how it would have to be in order for more than one of them to cohabitate the same program; worse, many people who do not understand this actually favor this trait as a way to allow them to "simplify" their task -- and as a result, they implement singletons when they "only want one" right now, and come to regret it later when they find out they actually need two or more -- Singleton as an up-front design pattern should only be considered (end even then, not always accepted) when two instances *cannot* coexist, ever, by reasons or requirements that are beyond your control. And the kicker is that a simple global can be cajoled into providing all the essential properties of a singleton design for essentially zero implementation cost -- With the kind of Singleton people write to feel like good OOP citizens, you actually have to write a bunch of code to participate in all their pitfalls and downsides. Sheesh!

throw table_exception("(? ???)? ? ???");

Advertisement

The service finder is better than the singleton. The well-known instance (a pointer a static global pointer initialized during program startup that points to the current version) is better than a singleton. Even the global static variable that delays application startup is better than the singleton in nearly every case.

In all these cases you can still have an instance that everybody uses, you can still have your hidden background dependency that no code acknowledges. But you can do it without the singleton.

Just because you only have one right now does not mean you should prohibit the option to only have one ever.

It seems the common example people give of a "good" singleton is a logging system. But even there, what if I am building and debugging a system and want my own private logger that points to a different logging destination for my own debugging purposes? If it is a singleton, I am forbidden from it.

Having a single instance of something is not a problem. There are many objects out there where you only ever need a single instance. However, that is radically different from the Singleton. The Singleton means you can only have one instance ever, and are forbidden from creating another. A Singleton means you are forbidden from ever creating more than a single instance; it follows that you are also forbidden from copying it, from cloning it, from abstracting it, from subclassing it, from testing it (you cannot use mock objects), from parallelizing it, and so on.

Singleton != happening to only have a single instance. Singleton means much stricter requirements.

There are several development issues that need to be overcome, they can be addressed without the Singleton problem.

Shared state is a difficult problem. There are situations where multiple systems need to know about details from other systems, sharing their state. This should be minimized by using accessors and mutators rather than directly modifying values, by using event listeners that get notified when values are changed so they can respond and update, and by other methods. This is a case where you tend to need only a single instance that maintains the state, but that is very different from a Singleton. Remember that happening to have only a single instance != Singleton.

It is common to have a collection of well-known objects. For example, you may have a structure configured at the start of the game containing pointers to the simulation, to the renderer, to resource stores, to game state, and to the application logger. These should still not be implemented as a singleton where there can only be one instance ever, but instead as a central location for discovering the shared information.

It is common for dependencies to be changed at runtime. You might replace entire systems like dropping in a new network controller when you connect or disconnect from servers. Some beginners think this means you need a Singleton class to guarantee that only one item is active. Instead you can use a well-known instance that serves as a redirector to the currently active instance.

Trying to stay on topic, an example could be a global instance of a structure something like this:

struct GloballySharedObjects {

Simulator* simulator = NULL;

Renderer* renderer = NULL;

NetworkCore* network = NULL;

MeshStore* meshStore = NULL;

TextureStore* texStore = NULL;

AudioStore* audioStore = NULL;

MusicStore* musicStore = NULL;

ILogger* log = NULL;

...

};

Elsewhere:

// Global object so we can share state. The hidden dependencies should be avoided if possible, but still better than singleton.

GloballySharedObjects gs;

Then you can build all your parts for resource management: A store, a cache, a loader, and proxy objects. They can be swapped out as needed, all without a singleton.

I really want to start coding but I'm stuck too much time on the design. This is really depressing =[

If there is one lesson that I've learned with coding it is that taking this inbuilt sense of "I have to do everything perfectly" that I have and throwing it out the window is the path to greatness.

Coding is one of those things where you more or less cannot design a useful system without having firsthand experience with it. That applies to any coding topic really. Sometimes the best thing to do is just jump in the deep end and fix problems when you run into them.

If anyone here started coding a game and were say, asked to code an input handling system and they just threw together some masterpiece of technology I would love to meet them, I would hazard a guess most of us made really pathetic attempts at new specializations of coding even if they had a ton of prior experience in the language, some stuff just takes revision to make pretty.

Looking at code and thinking that will teach you and you can just mimic their style also doesn't work, coding isn't like watching someone cut wood with a saw, it has thousands of levels of depth that only time and attempts and coding the thing yourself will really cement into your mind.

This topic is closed to new replies.

Advertisement