• Mathias (unregistered)

    I like this new trend of Remy's comments in CodeSOD articles.

  • AGray (unregistered) in reply to Remy Porter
    Remy Porter:
    I still probably wouldn't go Singleton, but that's because I'd want multiple SoundManagers governing different varieties of sound. One SM for effects, one SM for background music, one SM for menu operations, etc.

    This allows them to be compartmentalized in different threads if necessary (the effects SM should run in the game thread, the background SM should run in the global thread, ditto on the menu one).

    The real constraint would be something more along the lines of each game object can be observed only once by a given kind of SoundManager. The effects and music manager can both observe the spaceship, but only one effects manager can observe the spaceship- if another tries to register it either throws an exception or replaces the original effects manager.

    Further, in a situation like this, the GameEngine object should have the freedom to manage its child objects as it sees fit. If the GameEngine decides its a good idea to have one and only one SoundManager, then it can create only one. If it decides there should be more than one, it can make more than one. By making it a Singleton, you've said that the SoundManager knows best, and no one should ever create any more instances of the SM, which likely isn't true.

    Singelton enforces statically a condition that usually should be enforced by convention.

    Ironically, I have a singleton in the application I'm writing. I'm not opposed to the pattern itself, but it's definitely overused.

    Thanks for those insights!

    The reason I use a Singleton in this case is actually not as a worker, but as a persistent cache of settings.

    Yes, I know it's akin to the idea of Global variables in an Object-Oriented program, which is a WTF in its own right, but given that I have to store and load this information from save files, as well as make it persist across scenes/application states, I am finding it simplest and most maintainable to do it this way in this instance.

    My actual control is happening via other objects - the Maestro object I mention in my blog post monitors those Settings and knows how to interpret a PlaySoundEffect instruction, or tell the AudioSource (a Unity object) how to change background music. Settings GUI performs the value-set operations, obviously, as will Game Load system when that is implemented.

    As a rule in my own development, I only use a singleton when an object fulfills the requirement that under any circumstances, one and only one of it should exist at any given time. It's an easy pattern to abuse, as you (and others) have shown.

  • Dave Insurgent (unregistered)
    The reason I use a Singleton in this case is actually not as a worker, but as a persistent cache of settings.

    You mean it's almost like it is a Repository of settings?

    How do you test your code that uses that object in a manner that isolates that object?

    I don't think adding eventing to your system is at all too big of a deal: unless you throw away your game engine every time, in which case there's plenty of other WTFs in what you're doing and you have yourself a big ol' WTF onion.

    If you don't have eventing and a clear separation of concerns, then you likely have a deep, or going to be deep, object hierarchy too... a Player might be a Character and a Monster is also a Character and yadda yadda yadda.

    Eventing and data-driven go well together and will let you have testable, resuable, separate and maintanable code.

    You can also use DI without the framework, in which case, yes, your AudioEventHandler should get an instance of the SoundManager provide to it - when you use Singleton, you're explicitly coupling that SoundManager implementation to it's use. You're doing the same thing, you just for some reason think it's more readable to have the dependency implicitly wired all over the place, rather that explicitly in the constructor.

    Also, by wanting "one instance" of something, you basically set yourself up for issues with multi-threading (not so bad) and multi-process (a complete fucking disaster). Maybe not relevant to a tiny game, but in a web application, youre almost guaranteed to be multi-process at any scale except prototyping.

  • Jeff Dege (unregistered) in reply to Remy Porter
    Remy Porter:
    Further, in a situation like this, the GameEngine object should have the freedom to manage its child objects as it sees fit. If the GameEngine decides its a good idea to have one and only one SoundManager, then it can create only one. If it decides there should be more than one, it can make more than one.
    And who decides how many GameEngines there are?

    Or if you're using a DI engine, who decides how many DI engines there are?

    I'm working on a code-base that had a large number of singletons. In adapting it over the years, we've made significant changes to what goes on under the hood. A call to Logger.getInstance() no longer returns a static instance member, it forwards the call to a single instance of a SingletonManager class, which returns the appropriate instance of a Logger. In essence, we now only have a single singleton, the SingletonManager. Except that it doesn't actually construct itself, it relies on SingletonManagerStore - which is an abstract class with different implementations for different environments. One that stores the SingletonManager in memory, for normal executables, one that stores it and retrieves it from HttpContext.Current.Session, when used in ASP.NET, etc.

    Underneath, you could argue that this isn't actually singleton, anymore. But for the coder who's calling Logger.getInstance(), it looks like it's a singleton.

  • Garrison Fiord (unregistered) in reply to Mathias
    Mathias:
    I like this new trend of Remy's comments in CodeSOD articles.
    Me too. As long as he doesn't write long articles that are gayed up by unicorns.
  • RandomGuy (unregistered) in reply to Erik
    Erik:
    TRWTF is the singleton pattern!
    Could not agree more. Global variables are bad and hiding them in a singleton does not make them better.
  • Dave Insurgent (unregistered) in reply to Jeff Dege
    Jeff Dege:
    And who decides how many GameEngines there are?

    The user? By virtue of how many instances of the application they start?

    it forwards the call to a single instance of a SingletonManager class, which returns the appropriate instance of a Logger.

    Why not LoggerFactory instead of a (presumably) multi-use SingletonManager?

  • Harrow (unregistered) in reply to lmm
    lmm:
    If you can't call getInstance() on it, is it still a singleton?
    It is a zeroton.

    -Harrow.

  • AGray (unregistered) in reply to Dave Insurgent
    Dave Insurgent:
    The reason I use a Singleton in this case is actually not as a worker, but as a persistent cache of settings.

    You mean it's almost like it is a Repository of settings?

    That's a much more concise way of putting it...really, it is a Repository. Its only concern is the storage and persistence of data. Other things, such as the Settings GUI and Maestro, consume this data.

    How do you test your code that uses that object in a manner that isolates that object?

    I don't think adding eventing to your system is at all too big of a deal: unless you throw away your game engine every time, in which case there's plenty of other WTFs in what you're doing and you have yourself a big ol' WTF onion.

    I actually don't have to worry about throwing things away too much, given the way Unity is set up. Also, eventing is a core concern of Unity; it provides a rather nice event system that I take advantage of in a number of ways, including the application of the saved settings.

    If you don't have eventing and a clear separation of concerns, then you likely have a deep, or going to be deep, object hierarchy too... a Player might be a Character and a Monster is also a Character and yadda yadda yadda.

    Eventing and data-driven go well together and will let you have testable, resuable, separate and maintanable code.

    While I agree a deep hierarchy should be carefully considered, having a hierarchy is not necessarily a problem.

    The case you gave, while I use different terms in the code I've developed, is an apt one. An entity that can be engaged in a battle is...well, an Entity (has a health system and combat rolls, pretty much). In a standard JRPG there are two types of combative entities - players, and enemies.

    What is the difference between enemies and players? Players equip Equipment and Aethos (the customization system of the game...just nod and continue...), while Enemies drop various things, like Consumables and Equipment.

    On that note, Equipment, Aethos, and Consumables are all RPG Items. The abstract RPG Item defines a basic contract among items; the derived item classes state the applicable differences (e.g., you cannot Equip a Tonic, but you can drink it to restore 150 HP. Your Equipment confers stat bonuses, but Aethos also confer skills and stat bonuses, and further can level up to a certain point).

    You can also use DI without the framework, in which case, yes, your AudioEventHandler should get an instance of the SoundManager provide to it - when you use Singleton, you're explicitly coupling that SoundManager implementation to it's use. You're doing the same thing, you just for some reason think it's more readable to have the dependency implicitly wired all over the place, rather that explicitly in the constructor.

    Also, by wanting "one instance" of something, you basically set yourself up for issues with multi-threading (not so bad) and multi-process (a complete fucking disaster). Maybe not relevant to a tiny game, but in a web application, youre almost guaranteed to be multi-process at any scale except prototyping.

    First paragraph - I have no contest to this point. This is the downside of using a Singleton, and why I considered everything I know of before deciding to use a Singleton (which, is admittedly not much).

    Second paragraph - while this is not an issue for me at present (Unity handles multithreading behind the scenes for me), if I were to make my own custom game engine, you'd be right beyond a ghost of a doubt - I would almost certainly have to multithread or multiprocess to achieve playable performance.

  • Slapout (unregistered) in reply to @Deprecated
    @Deprecated:
    snoofle:
    What's wrong with that? It's easily discerned that the this in this singleton refers to this this from the singleton's point of view. From all other points of view, you should not be accessing that this, this this or the this, but the singleton via its getInstance, or pseudo-this.

    See? This is not so hard to understand!

    this.

    PS., Although I do not like replies that contain a singleton 'this', I will make an exception in this case.

    Shouldn't that be throw an exception in this case? :-)

  • Dave Insurgent (unregistered) in reply to AGray
    That's a much more concise way of putting it...really, it is a Repository. Its only concern is the storage and persistence of data.

    Right, which is why it might serve you well not to use a Singleton for it. You may test with an InMemorySettingsRepository or a MockSettingsRepository (or Fake, or whatever) - you may use a ProprietarySettingsRepository that uses a file format you create, or an XmlSettingsRepository. Or a CloudSettingsRepository.. just saying, you may need one or more of those a any point. I don't see how Singleton helps you here.

    I actually don't have to worry about throwing things away too much, given the way Unity is set up. Also, eventing is a core concern of Unity; it provides a rather nice event system that I take advantage of in a number of ways, including the application of the saved settings.

    Sure, but if that's all you're using it for I think you're selling yourself short.

    While I agree a deep hierarchy should be carefully considered, having a hierarchy is not necessarily a problem.

    Well, I am not a professional game developer, but I have seen some interesting material about how absolutely insanely large commercial games can get when the use inheritance to model game logic/rules/concepts. Inheritance is an is-a approach, and while it's really easy to agree that Equipment is an Item, and so is a Consumable, it's not always going to be that simple. What about Equipment that can only be used once? Is that a Consumable? Or does Consumable imply that the player actually eats it? What then is the property that actually causes those objects to diminsh? Do you call them Finite? Is a Sword a piece of Equipment that implements Repairable, Damaging and so on? It seems appealing to try to categorize things that way, but I think it's a lot easier to manage when instead you think that a Sword is an Item with a Set<Attribute>. You can then have CompositeAttribute use the Specification pattern to define valid/invalid Attribute definitions (for example, Indestructable can not be Repairable) - this is harder to do with interface/multi-inheritance. You can also externalize those definitions which makes your game-engine really reusable because you don't have a compile-time definition of what is/isn't possible.

  • (cs)

    The code used to get the instance isn't shown, but I assume it would typically be something like this:

        KpiService k = (new KpiService()).getInstance();

    After all, if one Lone Ranger is good, a legion of them would be better, right?

  • DB (unregistered) in reply to szeryf

    HAHAHAHAHA! (More non-spam text?_

  • jay (unregistered) in reply to Remy Porter
    Remy Porter:
    And you should avoid using the Singleton pattern. It's one of those patterns that's so easy to implement and seems so useful that you're tempted to create a bunch of them, but they should be used rarely.

    I think there's a missing step in this (no pun intended) logic.

    As stated, the best I can make of this argument is, "This thing is easy to use and is very useful, therefore you shouldn't use it."

    Like, "You shouldn't do addition in your programs. The plus operator is very easy to use and does addition easiy, so your'e tempted to use it to much."

  • jay (unregistered) in reply to T
    T:
    TheSHEEEP:
    (...) What would be better? Passing an instance of the "SoundManager" to each an every class that may want to play a sound? Limiting what classes should be able to play a sound? What good would come of that?

    Obviously you should've used Dependency Injection framework. No matter that your game would be slower, larger and harder to maintain.

    But seriously, singletons are quite error prone in enterprise applications (clustering). Often they're used as lazy shortcuts. Environment can't manage them. Switching to another implementation can be painful.

    I see nothing wrong in using them in desktop applications or games.

    Well, if you have a clustered app, then you can't implement a singleton with the simple "private static MySingleton instance" approach. You need to store the singleton somewhere that will be "single" for the whole app, not just "single" to one node on the cluster. I suppose you could say that singletons don't scale, that is, if you have an app that was written for a single server, and that app uses singletons, you can't necessarily just drop it into a clustered-server environment. You'd have to look at how the singletons were implemented and probably redesign them. I'll agree that that's an argument against singletons as currently implemented given today's state of the art. But one could argue that that's a deficiency in current language implementations rather than in the concept of a singleton. The same objection would apply to all static data (shared data for you VB folks).

  • glopal (unregistered) in reply to snoofle

    The getInstance method should instantiate the instance variable using the constructor, which should be private. No?

  • (cs) in reply to Dave Insurgent

    GoF included things like Vistors and Decorators and Delegates specifically because is-a relationships can get very complex and multiple inheritance is a potential nightmare.

    As a general rule, any hierarchy deeper than three levels needs to be justified. This goes for inheritance trees, file organization schemes, and slide presentations.

  • (cs) in reply to jay

    The operative word is that it seems useful, not that it is useful. Global variables also seem useful, and they are really easy to implement- at least until you have to support them. Then you discover how much spaghetti they actually create.

  • jay (unregistered) in reply to Remy Porter
    Remy Porter:
    There are a lot of ways to provide sound functionality. One way that would be vastly superior to a Singleton is to use the Observer pattern. A single SoundManager instance registers interest in game objects. When sound-worthy events occur in those objects, the SoundManager matches them up with a sound.

    This approach lends itself to building a declarative system for linking sounds to events, making it easier to modify your game later. It also means that sound can be added to classes without changing the classes themselves. Why should a spaceship know how to make noises? It's a spaceship- noises are nothing more than a side-effect of what it does when it's doing far more interesting things.

    Hmm, interesting, but I don't see how this would be superior to implementing a SoundManager singleton.

    I don't know exactly how the original poster implemented this, but logically you could create a "playSound" function that takes an argument that describes what sound. Like "SoundManager.getInstance().playSound(FIRE_PHASORS)". The spaceship class then doesn't know anything about how to play sounds. It just knows to call the sound manager to do it. If you decide to change the sound the spaceship makes, you change the code in playSound, not in the spaceship class. Responsibility is properly delegated.

    To accomplish what you're describing, every class that is associated with a sound would have to provide a hook to declare a listener. Then it would have to call the listener when it was time to play the sound. So instead of a single playSound call, we now have to define a listener field, create an addSoundListener function, and then we still have to call soundListener.playSound. Then we have to write code in another class that registers the sound listener with the spaceship object. Instead of one line of code, we have 10 or 20 lines of code to accomplish the same thing, split across at least two classes and four or more functions.

    And what have we gained? It gives us the ability to have multiple, different sound managers, so we can register different sound managers with different "sound-producing" objects. Maybe there's value in that, but I doubt it. If different sounds are produced in different ways -- like some are produced by playing an AVI file while others are synthesized internally with code -- we could handle the distinction in the sound manager based on the sound identifier passed in. This would probably be easier than having multiple sound managers registering themselves.

    If you are creating a game engine API where the sound manager is not part of your API, an observer pattern might be a good idea as it lets the caller supply its own sound manager. That's about the only case I can think of where it would offer an advantage.

  • Dave Insurgent (unregistered) in reply to jay
    The spaceship class then doesn't know anything about how to play sounds.

    Why does the spaceship know about sound at all?

    those sounds emit in response to events generated by the spaceship.

    i'd want my spaceship to fire a weapon, and that to produce a weapon_fire event, which the sound system observes and produces based on the type of the weapon. that way, if a turrent also has a weapon which can fire, it's all done. I don't have to worry about forgetting to make the turrent play a sound when it shoots.

  • This-tle and sham-rock (unregistered) in reply to snoofle
    snoofle:
    What's wrong with that? It's easily discerned that the this in this singleton refers to this this from the singleton's point of view. From all other points of view, you should not be accessing that this, this this or the this, but the singleton via its getInstance, or pseudo-this.

    See? This is not so hard to understand!

    ^ This.
  • (cs) in reply to jay

    The starship class needs to know that PHASORS make sounds. Why? What happens when we change our business rules and decide that PHASORS only make sounds in certain conditions. Do we put that logic in the SoundManager or the starship class?

    As I stated in a different comment, a better approach would be to let the GameEngine manage this. In each tick of the game, the GameEngine passes the relevant portions of the object graph off to the SoundManager and the Renderer objects. The observer pattern is, admittedly, overkill, but the Singleton pattern is hiding simplicity in global variables, which means lots of spaghetti code.

    The starship object should be focused on the business rules of starships. How to move. How to shoot. How to update stats as it takes damage and consumes inventory. Other objects should be responsible for deciding that sounds need to be played.

    I wrote a Singleton last week. I have a a set of Handler classes. I have a service that receives requests. Each request can be handled by a different type of Handler. I wrote a Singleton to use as a Factory; it uses reflection to find all concrete classes that implement the Handler interface and creates instances of them. When a request comes it, it invokes the CanHandle method on each Handler to find the Handler that's suitable for that request.

    I chose to make that factory a Singleton because a) I don't want to reflect the assemblies for each request, and b) it's possible that the instantiation of a Handler might be expensive.

    Now, only one class ever actually creates an instance of the Factory, and the beauty of that is that it allows me to restrict object creation. My Singleton is not, and could not be used, as a global variable. The internal/package/friend access modifier exists for a reason.

    As a side effect of this design, the individual Handlers are singleton by convention. I never create more than one instance, but I could if I ever wanted to. The Handlers are completely reusable. They're also stateless-by-convention, and there's a rule I wish I did have: "This class and all its children are stateless, and may not implement any data members."

  • Fakeyede Mobolaji (unregistered) in reply to snoofle

    That code is not OK. Should have been somrthing like this

    public static KpiService getInstance(){ return instance ?? instance = new KpiService(); }

    private KpiService(){ }

    Notice the constructor is private (This way, u can't just create a new KpiService. You have to go through getInstance() to get the singleton object

  • Fakeyede Mobolaji (unregistered) in reply to Fakeyede Mobolaji

    That code is not OK. Should have been something like this

    public static KpiService getInstance(){ return instance ?? (instance = new KpiService()); }

    private KpiService(){ }

    Notice the constructor is private (This way, u can't just create a new KpiService. You have to go through getInstance() to get the singleton object

  • jay (unregistered) in reply to Remy Porter
    Remy Porter:
    The operative word is that it seems useful, not that it is useful. Global variables also seem useful, and they are really easy to implement- at least until you have to support them. Then you discover how much spaghetti they actually create.

    When global variables are used to pass parameters between functions, they are horriby evil. I absolutely agree with that. But that doesn't mean that global data is always evil. Some data is rightly global.

    I used to work at a company where the programmers were always looking for new ways to create global data. They would put EVERYTHING in session variables. Then we'd have all this dangling junk data sitting in the session. When someone came back to modify the program, it was almost impossible to figure out who put the data there or what it was for. The connections between modules were lost. When we beat that out of them, they started putting function parameters in static fields. After a few more beatings, they had to find other tricky places to hide it. For some reason people just couldn't get the idea to pass parameters between functions as, say, function parameters. I went crazy at that place.

    But that doesn't mean that global data is never appropriate. It makes good sense for data that legitimately applies all over the place and which there should be only one copy of. Like, what's the user's timezone? Many modules might use that. Rather than pass it in and out of 1000 places, it makes sense to keep it in a global somewhere. Or user preferences. Yes, we could load preferences in a start-up function and then pass them to everything, but it's a pain and it gains nothing.

    What's the difference? When data applies to the application as a whole, it's legimately global. When it applies to one particular thing we're doing right now, it is not legimately global. What is the current user's name? Fair game for global. What is the name of the customer on the transaction we are currently processing? Not fair game for global at all.

  • (cs) in reply to jay

    I'm not saying "Never use singletons" or "never use globals". But they should be used sparingly. And for the most part, singletons should be implemented by convention, not by pattern.

    Globals for things that are truly global, singletons for things that are truly singular.

  • Dave Insurgent (unregistered) in reply to Remy Porter
    Do we put that logic in the SoundManager or the starship class?

    I'd put that logic in the PhaserEventHandler which listens for PhaserFireEvent and then, based on the attributes of the Phaser that is being fired, play a sound. Just like, if instead it were a SniperRifle and it had a Silenced attribute, the handler would play a different sound.

    The idea that the Player knows that their SniperRifle makes a sound isn't very useful, and it means that they need to know about the assets involved (either directly as resources, or indirectly as method calls: playSilencedSniperRifleSound()).

    When I shoot a gun, the air around me makes the sound, not me.

    The starship object should be focused on the business rules of starships. How to move. How to shoot. How to update stats as it takes damage and consumes inventory

    Why? This is dogma. The starship is just a set of data: it is the union of a Thruster, a Hull, a Shield and a Weapon.

    When the player presses X, the Thruster emits an event indicating that it is active. The game engine delegates that event through handlers which then apply forces to the various entities that represent the physical model of the ship. The rendering subsystem updates the view of the ships physical model based on the observation of its physical state. Does the Ship need to know how it collides with other ships now, too? There's virtually no limit here.

    I wouldn't even have a Ship class. It's just a definition of a set of attributes that themselves may be composed of other primitive attributes in a very shallow hierarchy.

    it uses reflection to find all concrete classes that implement the Handler interface and creates instances of them. When a request comes it, it invokes the CanHandle method on each Handler to find the Handler that's suitable for that request.

    You used a Singleton to facilitate Chain of Responsibility. I don't see how the former is needed for the later.

    Now, only one class ever actually creates an instance of the Factory,

    Then your concerns about performance were a little unnecessary and your design decision seems tantamount to premature optimization.

    They're also stateless-by-convention, and there's a rule I wish I did have:

    You mean immutability?

  • dogmatic (unregistered) in reply to Remy Porter
    Remy Porter:
    A single SoundManager instance registers interest in game objects. When sound-worthy events occur in those objects, the SoundManager matches them up with a sound.

    Hey, you know what would be a good pattern to enforce that there is only one instance of this SoundManager class? lol

    I too don't get the singleton hate. I agree that if you have more than what you can count on one hand in any given application you probably are over-using them, but I will use them any time there should only ever be one instance of a class. I have made a SoundManager singleton for some apps. And in a couple lightweight MVC frameworks I've developed, the controller class is a singleton.

  • (cs) in reply to Dave Insurgent
    Dave Insurgent:
    The starship object should be focused on the business rules of starships. How to move. How to shoot. How to update stats as it takes damage and consumes inventory

    Why? This is dogma. The starship is just a set of data: it is the union of a Thruster, a Hull, a Shield and a Weapon.

    If a Thruster is a meaningful object in your context, fine. But we're getting too bogged down in the details of a hypothetical application and losing track of the core premise: objects should be focused on doing the job of being themselves. If we're building a Galaga clone, you've just terribly over-designed the application.

    Dave Insurgent:
    Now, only one class ever actually creates an instance of the Factory,

    Then your concerns about performance were a little unnecessary and your design decision seems tantamount to premature optimization.

    Only one class actually creates an instance of the Factory. I didn't mention how many instances of the client class there were. There will be a large number of clients accessing the Factory.

    Dave Insurgent:
    They're also stateless-by-convention, and there's a rule I wish I did have:

    You mean immutability?

    Immutability and statelessness are not the same, but I'd be fine with immutability as well. There are OO languages that have things like that, and there are plenty of functional languages that do.

  • Dave Insurgent (unregistered)
    When I shoot a gun, the air around me makes the sound, not me.

    Just to expand on this:

    If the person firing the Weapon is the one who has to play the sound, they they must also become aware of all the rules that could alter how the sound is played. This is a clear violation of SRP.

    This means that if the Ship can fly in to the atmopshere as well as out in space, and you want to accurately model the fact that sound doesn't travel in space (nevermind why: that's irrelevant) - then suddenly your ship has to be able to tell if it is in space or not. I'm not talking about a HUD saying "You're now in space d00d!!!1elevent" - I'm talking about, at a code level, the spaceship now needs to be able to perform a test, or acquire information from somewhere ... and guess what? That leads to SomeSingleton.getInstance().isInSpace(this) or just a static method call. And if you want to add this feature, you have to go through and do it everywhere that plays sound. This is not DRY at all.

    Whereas, in the WeaponEventHandler (I wouldn't even have Phaser as a class/event handler), I could add that check, and it might not be very pretty, but at least it is in one place. It's no less pretty than putting it in the class 'using' the Weapon, but it's a lot more maintainable/testable.

    Then again, you could set up a Chain of Responsibility in the WeaponEventHandler at that point, refactor the old one to be a TerrestrialWeaponEventHandler and a SpaceWeaponEventHandler and so on and so forth.

  • Thuktun (unregistered) in reply to snoofle

    The constructor is public, allowing anyone to create a new singleton whenever.

    Nowhere in the cited code is that construction initiated; if the "SNIP" section only contains functional bits of the singleton, the singleton is relying on something external to initialize it by constructing only one of these.

    One can easily find the Right Way to do this by doing a bit of Googling,or alternatively by using a framework like Spring that provides baked-in singleton initialization.

  • AGray (unregistered) in reply to Dave Insurgent

    [quote user="Dave Insurgent"][quote]That's a much more concise way of putting it...really, it is a Repository. Its only concern is the storage and persistence of data.[/quote]

    Right, which is why it might serve you well not to use a Singleton for it. You may test with an InMemorySettingsRepository or a MockSettingsRepository (or Fake, or whatever) - you may use a ProprietarySettingsRepository that uses a file format you create, or an XmlSettingsRepository. Or a CloudSettingsRepository.. just saying, you may need one or more of those a any point. I don't see how Singleton helps you here.[/quote]

    You have a point here. Depending on one's opinions on the Singleton, a singleton just does the same thing with a different flavor.

    If you look at my webplayer, there are three actions the user can take on the title: Settings, New Game, and Load Game. Settings serves to set the settings up from the title screen, such that when a new game is started, the user already has their settings set up. The Load Game option is just going to overwrite that when it loads from the save file.

    The point I think I see from your argument is, instead of using a singleton, just create class(es) that live in the background (like the singleton currently does), and serve up information as it is needed (e.g. sound settings repo, graphics settings repo, etc.) It's easier to test by using unit tests, etc.

    I have to admit - I berate myself for not thinking of the problem in that way. Lack of experience on my part; I'll give that setup a shot!

    [quote]I actually don't have to worry about throwing things away too much, given the way Unity is set up. Also, eventing is a core concern of Unity; it provides a rather nice event system that I take advantage of in a number of ways, including the application of the saved settings.[/quote]

    Sure, but if that's all you're using it for I think you're selling yourself short.[/quote]

    I'm a bit confused by this statement. What other possibilities do you see?

    [quote]While I agree a deep hierarchy should be carefully considered, having a hierarchy is not necessarily a problem.[/quote]

    Well, I am not a professional game developer, but I have seen some interesting material about how absolutely insanely large commercial games can get when the use inheritance to model game logic/rules/concepts. Inheritance is an is-a approach, and while it's really easy to agree that Equipment is an Item, and so is a Consumable, it's not always going to be that simple. What about Equipment that can only be used once? Is that a Consumable? Or does Consumable imply that the player actually eats it? What then is the property that actually causes those objects to diminsh? Do you call them Finite? Is a Sword a piece of Equipment that implements Repairable, Damaging and so on? It seems appealing to try to categorize things that way, but I think it's a lot easier to manage when instead you think that a Sword is an Item with a Set<Attribute>. You can then have CompositeAttribute use the Specification pattern to define valid/invalid Attribute definitions (for example, Indestructable can not be Repairable) - this is harder to do with interface/multi-inheritance. You can also externalize those definitions which makes your game-engine really reusable because you don't have a compile-time definition of what is/isn't possible.[/quote]

    I love this bit here. I am going to write a blog article on it. I did some really good thinking over lunch on it.

    To answer some of the questions, I can invoke "A wizard did it." By that, I mean, in my specification of the system, I've already defined business rules like, "Equipment and Aethos cannot be Consumables." (Though that would be interesting; imagine whacking an enemy with a gummy sword, then eating part of it to restore HP! I'm thinking about that one too, btw!)

    That being said, I also see YOUR way of things - what if, in a future project, I want items to be degradable? What if I want to implement the Gummi Sword? The way you defined would be better.

    So, well-stated...I've got much more to consider going forward. And that's a good thing; player stats were what I was looking at working with next...

  • Dave Insurgent (unregistered) in reply to Remy Porter
    But we're getting too bogged down in the details of a hypothetical application

    I disagree. I'm advocating for a data-driven model, which is philosophically different than your object-orieted model, and I'm trying to demonstrate why games specifically seem to be a good candidate for it.

    I too like rich domain objects, but what are those domain objects? I'm proposing that in a robust game engine that is easy to work with and appropriate for multiple purposes, the domain is a much smaller set of data than the higher order combinations you're operating with.

    Immutability and statelessness are not the same

    Oh, I agree - but they both exist in a way that produces no side effect on themselves. Can you think of a time when using one would be appropriate, but not the other? (Performance or memory aside, I mean, from a correctness perspective).

  • Lon (unregistered)

    There's lots of things wrong with this.

    1. Using getInstance() in the normal way never created an object.

    KpiService.getInstance().foo() - never calls constructor.

    1. Even if you did artificially create an object and then use the singleton access getInstance() such as:

    KpiService junk = new KpiService(); KpiService.getInstance().foo();

    It would be possible to change the instance variable by creating another KpiService object, thus violating the whole singleton concept.

  • Dave Insurgent (unregistered)
    I love this bit here. I am going to write a blog article on it. I did some really good thinking over lunch on it.

    I'd like to read it - feel free to send an e-mail to doug dot moscrop at gmail dot com - if you're so inclined - when you post it.

  • Dave Insurgent (unregistered)
    That being said, I also see YOUR way of things - what if, in a future project, I want items to be degradable? What if I want to implement the Gummi Sword? The way you defined would be better.

    Not to mention you can also write automated acceptance tests for them, so that your game, as an application of your game engine, is driven not by the "wizard specification" (nicely put), but by an actual spec - that maybe someone else a little more 'product-oriented' or 'business-oriented' (almost like an analyst... for business!) writes themselves.

  • (cs) in reply to TheSHEEEP
    TheSHEEEP:
    I don't get the bashing SIngletons get in general.

    The usual argument is: It is bad style. Uh-huh. Is that so?

    In a game I once made I had a singleton that allowed to play a fire-and-forget sound. It was very useful that I could do so from each place in the code, from where loading was finished to when a weapon was fired (both were obviously in very different parts of the code).

    What would be better? Passing an instance of the "SoundManager" to each an every class that may want to play a sound? Limiting what classes should be able to play a sound? What good would come of that?

    Of course, a singleton should actually be implemented correctly ;) And of course, some things should not be a singleton, as they really shouldn't be usable everywhere. But saying that the pattern itself sucks because you are not capable of using it correctly does really put me off.

    I guess, like with many things, a singleton can be used to do something wrong, and therefore, some seem to think that it is generally bad.

    Your game objects have no business knowing about higher-level objects and generally no business knowing about siblings either (e.g., player doesn't need to directly manipulate ememy; if he could why not just set enemy's health to 0 and call it a day?). You want to have higher-level manager classes that contain state for the game and manipulate all of the objects.

    For example, if your game objects themselves detect collisions, then which is correct? player.checkCollision(enemy) or enemy.checkCollision(player) or both? What about collisionManager.check(player, enemy)?

    Singletons can get the job done, but it's not ideal. They allow you to be lazy and not think things through. This results in terrible design decisions that don't actually make any sense at all, but are allowed to happen because of the global state. Most importantly, just because you only need one of something doesn't mean that you have to assert that only one of something can ever exist. That's just dumb. It prevents object-oriented programming from being used as intended.

    Watch this if you haven't yet and be enlightened:

    http://youtu.be/-FRm3VPhseI

  • AGray (unregistered) in reply to Dave Insurgent
    Dave Insurgent:
    That being said, I also see YOUR way of things - what if, in a future project, I want items to be degradable? What if I want to implement the Gummi Sword? The way you defined would be better.

    Not to mention you can also write automated acceptance tests for them, so that your game, as an application of your game engine, is driven not by the "wizard specification" (nicely put), but by an actual spec - that maybe someone else a little more 'product-oriented' or 'business-oriented' (almost like an analyst... for business!) writes themselves.

    TDD in a nutshell...I've been exposed to it, and trying to integrate it into my very-indie dev ops at home.

    Well, we should thank the TDWTF staff - the WTF posted has helped one developer see another set of WTFs in his own work! Thanks Remy et al!

  • (cs) in reply to jay
    jay:
    I don't know exactly how the original poster implemented this, but logically you could create a "playSound" function that takes an argument that describes what sound. Like "SoundManager.getInstance().playSound(FIRE_PHASORS)". The spaceship class then doesn't know anything about how to play sounds. It just knows to call the sound manager to do it. If you decide to change the sound the spaceship makes, you change the code in playSound, not in the spaceship class. Responsibility is properly delegated.

    To accomplish what you're describing, every class that is associated with a sound would have to provide a hook to declare a listener. Then it would have to call the listener when it was time to play the sound. [...]

    And what have we gained? [...]

    If you are creating a game engine API where the sound manager is not part of your API, an observer pattern might be a good idea as it lets the caller supply its own sound manager. That's about the only case I can think of where it would offer an advantage.

    I was going to say pretty much the same thing, but there's another advantage. The spaceship only needs to fire the event once, and both the SoundManager and the ParticleEmitter systems will do their thing if they've registered their interest.

    In any case... what does this have to do with the whether to use singletons or not? Even in the case where Spaceship calls SoundManager:getInstance(), if what is returned is a singleton or not should be of no concern to Spaceship. It's purely an implementation detail of SoundManager.

  • AGray (unregistered)

    @Remy - Question.

    Reading the replies in between my exchange with Anonymous Dave, I notice he's not the only one who considers the Singleton as something that, while it appears helpful, is only half as helpful as the next best solution.

    You mentioned you're using a singleton in an app you're using. I would assume you're using it the "right" way (after all, you're an editor for TDWTF, not a regular submitter)...what/when is the right way/time to use a Singleton class?

  • wgeek (unregistered) in reply to snoofle

    One problem is that getInstance() will be called before the constructor unless the programmer explicitly "news" the object first. And why is the constructor public. Yeah, this is a WTF.

  • Jazz (unregistered) in reply to snoofle
    snoofle:
    It's easily discerned that the this in this singleton refers to this this from the singleton's point of view. From all other points of view, you should not be accessing that this, this this or the this, but the singleton via its getInstance, or pseudo-this.

    You sound like the love child of Nagesh and Immanuel Kant.

  • (cs) in reply to AGray
    AGray:
    public class Singleton
    {
      private static Singleton _Instance;
      public static Singleton Instance
      {
        get
        {
          return _Instance
                 ?? (_Instance = new Singleton());
        }
      }
      // ...Snip...
    
    And that still leaves a miniscule window of misopportunity for a race condition to occur between checking the value of _Instance and assigning the newly created Singleton object to it...

    If you want to get rid of that too, assign a newly created Singleton object to _Instance in it's declaration - such static variable initializers are guaranteed to run once and only once when the class is first loaded.

  • (cs) in reply to snoofle

    Is that the is that Clinton referred to? Is that the is that is? Or aren't?

    What the hell is a singleton? Something to do with a card game the last I knew. Why are we talking about a card game on TDWTF?

  • DarrenC (unregistered) in reply to Mcoder
    Mcoder:
    Why don't languages already come with a singleton modifier? It would remove an entire class of WTFs from the face of Earth (and create another entire and more entretaining class, so we can laugh more).

    We've had them since the dawn of time - they're called globals.

  • Meschelle (unregistered) in reply to jay
    jay:
    Remy Porter:
    The operative word is that it seems useful, not that it is useful. Global variables also seem useful, and they are really easy to implement- at least until you have to support them. Then you discover how much spaghetti they actually create.

    When global variables are used to pass parameters between functions, they are horriby evil. I absolutely agree with that. But that doesn't mean that global data is always evil. Some data is rightly global.

    I used to work at a company where the programmers were always looking for new ways to create global data. They would put EVERYTHING in session variables. Then we'd have all this dangling junk data sitting in the session. When someone came back to modify the program, it was almost impossible to figure out who put the data there or what it was for. The connections between modules were lost. When we beat that out of them, they started putting function parameters in static fields. After a few more beatings, they had to find other tricky places to hide it. For some reason people just couldn't get the idea to pass parameters between functions as, say, function parameters. I went crazy at that place.

    But that doesn't mean that global data is never appropriate. It makes good sense for data that legitimately applies all over the place and which there should be only one copy of. Like, what's the user's timezone? Many modules might use that. Rather than pass it in and out of 1000 places, it makes sense to keep it in a global somewhere. Or user preferences. Yes, we could load preferences in a start-up function and then pass them to everything, but it's a pain and it gains nothing.

    What's the difference? When data applies to the application as a whole, it's legimately global. When it applies to one particular thing we're doing right now, it is not legimately global. What is the current user's name? Fair game for global. What is the name of the customer on the transaction we are currently processing? Not fair game for global at all.

    So global constants are ok, not global variables?

    FWIW - I think configuration and some type of loggigns are two good examples where global stuff makes some sense - But in both of these instance is because the data is basically constant - and certainly pertinants to almosts all of the app. Loggings is a little more difficults because we may want to separate out multiple types of loggings....but assuming their is one globals error log it would makes much sense to alway be loggings through the same instance.

    But maybe not too...

  • I fix for you (unregistered) in reply to AGray
    Dave Insurgent:
    That's a much more concise way of putting it...really, it is a Repository. Its only concern is the storage and persistence of data.

    Right, which is why it might serve you well not to use a Singleton for it. You may test with an InMemorySettingsRepository or a MockSettingsRepository (or Fake, or whatever) - you may use a ProprietarySettingsRepository that uses a file format you create, or an XmlSettingsRepository. Or a CloudSettingsRepository.. just saying, you may need one or more of those a any point. I don't see how Singleton helps you here.

    You have a point here. Depending on one's opinions on the Singleton, a singleton just does the same thing with a different flavor.

    If you look at my webplayer, there are three actions the user can take on the title: Settings, New Game, and Load Game. Settings serves to set the settings up from the title screen, such that when a new game is started, the user already has their settings set up. The Load Game option is just going to overwrite that when it loads from the save file.

    The point I think I see from your argument is, instead of using a singleton, just create class(es) that live in the background (like the singleton currently does), and serve up information as it is needed (e.g. sound settings repo, graphics settings repo, etc.) It's easier to test by using unit tests, etc.

    I have to admit - I berate myself for not thinking of the problem in that way. Lack of experience on my part; I'll give that setup a shot!

    Dave Insurgent (I guess):
    I actually don't have to worry about throwing things away too much, given the way Unity is set up. Also, eventing is a core concern of Unity; it provides a rather nice event system that I take advantage of in a number of ways, including the application of the saved settings.

    Sure, but if that's all you're using it for I think you're selling yourself short.

    I'm a bit confused by this statement. What other possibilities do you see?

    Dave Insurgent (I guess):
    While I agree a deep hierarchy should be carefully considered, having a hierarchy is not necessarily a problem.

    Well, I am not a professional game developer, but I have seen some interesting material about how absolutely insanely large commercial games can get when the use inheritance to model game logic/rules/concepts. Inheritance is an is-a approach, and while it's really easy to agree that Equipment is an Item, and so is a Consumable, it's not always going to be that simple. What about Equipment that can only be used once? Is that a Consumable? Or does Consumable imply that the player actually eats it? What then is the property that actually causes those objects to diminsh? Do you call them Finite? Is a Sword a piece of Equipment that implements Repairable, Damaging and so on? It seems appealing to try to categorize things that way, but I think it's a lot easier to manage when instead you think that a Sword is an Item with a Set<Attribute>. You can then have CompositeAttribute use the Specification pattern to define valid/invalid Attribute definitions (for example, Indestructable can not be Repairable) - this is harder to do with interface/multi-inheritance. You can also externalize those definitions which makes your game-engine really reusable because you don't have a compile-time definition of what is/isn't possible.

    I love this bit here. I am going to write a blog article on it. I did some really good thinking over lunch on it.

    To answer some of the questions, I can invoke "A wizard did it." By that, I mean, in my specification of the system, I've already defined business rules like, "Equipment and Aethos cannot be Consumables." (Though that would be interesting; imagine whacking an enemy with a gummy sword, then eating part of it to restore HP! I'm thinking about that one too, btw!)

    That being said, I also see YOUR way of things - what if, in a future project, I want items to be degradable? What if I want to implement the Gummi Sword? The way you defined would be better.

    So, well-stated...I've got much more to consider going forward. And that's a good thing; player stats were what I was looking at working with next...

  • likeclockwork (unregistered) in reply to TheSHEEEP
    TheSHEEEP:
    I don't get the bashing SIngletons get in general.

    The usual argument is: It is bad style. Uh-huh. Is that so?

    In a game I once made I had a singleton that allowed to play a fire-and-forget sound. It was very useful that I could do so from each place in the code, from where loading was finished to when a weapon was fired (both were obviously in very different parts of the code).

    What would be better? Passing an instance of the "SoundManager" to each an every class that may want to play a sound? Limiting what classes should be able to play a sound? What good would come of that?

    Of course, a singleton should actually be implemented correctly ;) And of course, some things should not be a singleton, as they really shouldn't be usable everywhere. But saying that the pattern itself sucks because you are not capable of using it correctly does really put me off.

    I guess, like with many things, a singleton can be used to do something wrong, and therefore, some seem to think that it is generally bad.

    It's not necessary to be a singleton. No, you don't have to pass it everywhere. But it's just a global, or part of some other system which could be referenced and constructed as such. (game.soundmanager)

    Singleton method is usually just a way for people to have globals without having globals. Singleton is the diet soda of design patterns.

    Singleton makes a little sense if it's life-threateningly mission critical that there only be one instance. Otherwise you're just using your class itself as a container for a global variable, rather than storing the instance somewhere that actually makes sense.

  • (cs) in reply to AGray

    I won't claim that I made a perfect implementation of singletons, but I can at least promise that I thought about it before I did it.

    My pattern, as mentioned, was a Factory sitting atop a Chain of Responsibility. Creating the chain is potentially expensive- in this case, some objects might need to talk to the filesystem, a database, or some other resource-heavy store. Once the chain is created, however, each object doesn't expect it to change. Each object in the chain is stateless, or at least should be. Essentially I have a set of incoming requests, each request should be handled by an instance of the appropriate handler for that particular request.

    My reason for using a Singleton wasn't quite my own personal dogma: a singleton should wrap objects that are truly singular.

    Instead, I decided that an object should be singular because a) the objects it managed were stateless, b) creating those objects could be expensive, and c) I could control who accessed the singleton instantiator.

    And before you get too excited about TDWTF editors being magical fonts of programming wisdom, I have personally written up a few of my own WTFs as articles. In fact, I will give out some spoilers: I was the mentor in my next WTF, and was at least partially the source of the WTF. There are reasons I didn't route around it, but mostly it boiled down to a "Not my problem" situation.

  • Dave Insurgent (unregistered) in reply to Remy Porter
    Each object in the chain is stateless, or at least should be

    Sure, I'm not sure why that matters. Arguably, if you're using Singleton, I'd really expect them to be stateful, because that's what you wanted to do: capture universal state. Otherwise it would just be static method calls.

    I guess the alternative is that they're not stateful, but they do have some creation-time configuration.

    In the former case, using Singleton still presents the ususal problems of testability and you could still just use dependency injection to pass one instance around right from main.

    In the later, I don't see any reason to enforce the one-instance rule because either your performance concern is premature/inappropriate (if you follow the same dependency injection adherence as above) or a case for a Flyweight - which is to say, I'd like to have one instance, but is it incorrect to have more than one? How can that be, if they're stateless?

    I guess you could argue that they might end up configured differently..

Leave a comment on “The Lone Rangers”

Log In or post as a guest

Replying to comment #:

« Return to Article