質問

I'm in the midst of trying to teach myself programming. I started the same way that I'm sure most people start; making small, messy apps and games that do simple things in not-so-simple ways. Recently, I've been trying to take the next step by writing a slightly more complex game that uses OOP design to write better, more modular code!

The main issue I've been having is the design of my main StateManager (FSM) class (to switch between intro/menu/game/etc screen states). I've looked high and low, and I've only really seen two methods of designing them:

  • Use a switch/case statement + an enum to switch between states..

  • Make a singleton FSM class that handles pushing/popping states to/from a vector..

Now, my problem is, the switch case statement is very repetitive and clunky, and it kind of works against my goal of using this project to teach myself OOP.

My second, and bigger problem is the 'singleton' suggestion.

As I said before, I'm trying to teach myself, and I still have a lot to learn when it comes to programming, especially in the field of OOP and design patterns and all that stuff. I've run into an issue where, for EVERY single 'singletons are evil' thread and discussion that I find, I find just as many tutorials and references where people use singletons in their code to make 'engine' classes and FSMs. It's a very consistent mixed message.

I suppose I just don't understand why... Even if you only want/intend to have a single object of a class, why is it necessary/beneficial to make the constructor private and create a singleton? I've read a lot about how singletons are bad, how they are essentially global, how they get in the way of multi-threading, and how many programmers consider them overused or just plain bad design... Yet I see example after example of people using them, and very few counter examples showing alternate methods.

Couldn't the same type of thing be done with just a regular class? What's the purpose of explicitly restricting the creation of instances? I've heard only negative things about singletons, yet people seem to use them constantly... Am I completely missing something about singletons and OOP?

Is the use of singletons just a trend, or is it just a trend when people call singletons 'evil'? How do I get around this..? Isn't there something between the switch/case FSM and the singleton FSM?? Couldn't someone design their program's state system the exact same way without making any of their classes singletons? Would that change something? [confused]

役に立ちましたか?

解決

Couldn't the same type of thing be done with just a regular class? What's the purpose of explicitly restricting the creation of instances? I've heard only negative things about singletons, yet people seem to use them constantly... Am I completely missing something about singletons and OOP?

No, I believe you're on the right track: there's absolutely no reason to prevent the creation of two instances. The Universe won't implode because of that.

It's a completely unnecessary restriction. Since you have to manually code that restriction, it's quite silly to have it at all (if you had to write code to lift it, that would be another matter).

I suppose there may be weird and rare situations where the Universe does implode if a second instance is created, but that sounds quite farfetched. In any case, it doesn't justify the prevalence of singletons all over the Internet.

I can't really explain why people use them constantly without insulting the reasoning abilities of those people, so I will refrain from doing so.

Couldn't someone design their program's state system the exact same way without making any of their classes singletons? Would that change something?

The only thing it changes is that by making it a singleton you prevent yourself from creating throwaway instances for unit testing. Everything else just works the same.

他のヒント

As is often the case, there is no one simple answer. In C++, the singleton pattern also manages order of initialization issues, which are important if it is to be used in the constructors of static objects. And there are certain types of objects where multiple instances can only be a programming error; if you can prevent them, why not.

On the other hand, I have a great deal of difficulty imagining a case where a StateManager class should be a singleton. It is in no way managing some unique resource, or some meta-functionality (e.g. like logging) which by its very nature must be unique. And I can't imagine it being used in the constructors of static objects either.

A statement such as "singletons are bad" is very misleading; for some things, they are the most appropriate solution. But just because they aren't bad in the absolute doesn't mean that they are appropriate everywhere. They solve one particular, very limited problem. When you need to solve that problem, not using a singleton is bad. But (as is true for just about everything), using it when it isn't appropriate is bad.

I don't see why the FSM class should be a singleton. There are plenty of real-world FSM systems where there are no singletons, heck, there are some where the state instances are created and destroyed as the SM traverses the states, and where the state machine is itself a state to enable easy composability of hierarchical state machines.

In a complex application, you will have multiple state machines, some of them popping in and out of existence. The ones that handle, for example, client-server interaction, will necessarily have multiple instances that come and go with clients. Some others may benefit from composing multiple hierarchical state machines, some of which may be re-used in many places. Thus the idea that you'd have a state machine as a singleton class is silly to me. You may have, for example, an instance of a particular state machine in a singleton application class that encapsulates your application, but that's far from having a singleton class state machine.

To get a good overview of various state machine implementation techniques, including contrasts between flat FSMs and hierarchical state machines (HSMs), you'd want to get a look at Miro Samek's PSICC2 book. He has plenty of freely downloadable articles where common techniques are explained.

A reasonable C++ implementation of a hierarchical state machine, usable for UI, is available in the state machine framework in Qt.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top