• (disco) in reply to Masaaki_Hosoi

    What happens when you want to do local co-op? replays? those are both features that can be harmed by globals

  • (disco) in reply to Martin_Tilsted1

    Seems to me the problem is that you're combining a class' definition with the expectation that there will be exactly one instance. Under theory, anywhere that occurs, you can use a regular instantiation instead and then allow a different mechanism or system worry about ensuring that a single instance is created and provided to its intended scope of use. Standard dependency inversion.

  • (disco) in reply to riking
    riking:
    What happens when you want to do local co-op? replays? those are both features that can be harmed by globals

    In the case of local co-op, it's still one instance of the game but with two players. So yes, if you had the concept of one player at a time and stored a static reference to just the one player then co-op is going to be more difficult to add but only having one game manager doesn't really complicate things (I'd argue that having one game manager per player would, in fact, make things much harder than necessary). I have encountered this before though, when trying to add co-op to a demo that ships with Unity where each enemy assumed there was only one player and so one of the two players was always ignored by the AI.

    In the case of a replay, that depends on how the feature needs to work. In the case of a Halo-style theater mode, that could be fairly easily handled by having a separation between GameManager and GameMode (Unreal does this - there's a GameInstance and a GameMode, the former persists through the entire lifetime of the game whereas the latter only exists during gameplay and for the duration of a single level or map). A subclass of GameMode could act as a sort of stub, playing back announcer sounds and showing score but without actually submitting or saving any player data.

    If the replay needs to be played back in the middle of a game rather than saved for later (sports game, perhaps?) then I'd assume that could be handled as a state in an FSM for the game mode (maybe at the end of a round it transitions to a state for doing the replay, then after the replay finishes it transitions back to gameplay or perhaps to end of game state).

    I'd be interested to hear how you'd solve those, however, particularly how you'd make use of multiple game managers to do it - always curious to see how others solve problems :)

  • (disco) in reply to Masaaki_Hosoi
    Masaaki_Hosoi:
    I'd be interested to hear how you'd solve those, however,

    Two people above this post have explained what can be done. You can either give the same instance to all the things that need it, rather than having it figure out where things it needs are (Generally known as dependency injection, or common sense). The advantage to this route is that you aren't saying that the class can never be instantiated again, it just isn't being done, because there's no point, and you can pass in a different one if needed.

    The other is a static variable holding your current manager. Outside of your current manager. If everything looks there, you know where things get it, but you, again, aren't enforcing that only one instance can ever exist.

    It's a well known problem, with well known solutions.

  • (disco)

    If you have to pass arguments to the method that initializes the singleton.

    You might be a redneck.

    I mean, you don't have a singleton

  • (disco) in reply to TheCPUWizard
    TheCPUWizard:
    Most developers who actively study, publish and utilize Design Pattern based development strongly consider it an anti-pattern. Of course when you add in all the cargo-cult followers their numbers are dwarfed. Here are just a few of the many reasons:

    Among MacOS X and iOS developers, singletons are heavily and very effectively used. They usually don't care about the number of instances of a class in the universe, but realise that they only need one instance. They don't bother ensuring that only one instance exists through code, but through code reviews. But then they don't "actively study, publish, and utilise Design Pattern based development", but write apps that work and make money.

    What I detest is the sneaky way how you try to insult anyone disagreeing with you by calling them "cargo cult followers".

    That said, the code posted is not a Singleton, but a big WTF.

  • (disco) in reply to TheCPUWizard
    TheCPUWizard:
    1: True, but that does not make it an anti pattern. That makes it a pattern which should only be used in cases where you need to ensure that there is only one instance. This is sometimes exactly what you need.

    Something is an anti-pattern when it is demonstrated to cause more problems than it solves (compared to alternatives).

    I don't think that is a valid definition of an anti pattern. An anti pattern is something which seemed like a good idea, but which later turned out to cause problems.

    I think a typical usage of a singleton, is as a cache manager for loading external resources to ensure that a resource is only loaded once and then cached by the singleton.

    With that type of singleton, the main benefit is that you don't have to pass a object around to all your methods and constructors which might need to load resources. Methods which need to access resources just get the singleton.

    The main benefit a singleton pattern gives to its users is the "I know where to get a always initialized object", not the "There must be only one".

    This is also where most developers fuck up their design. They use a singleton, where they only need the "Give me an object which I can use as for example cache manager".

    So usage of singletons in large programs should in general be replaced by dependency injections, or simply a hash map which contains named objects with different responsibilities.

    Qutoe: (Aka forum quote is the true wft) "Every variable that can hold a reference type must be examined during a Gen2 GC. Declare a variable, or field within an instance and even when it is set to null there is a (very tiny) impact on GC. It has nothing to do with the collection of the object itself, and (almost) everything to do with the work required to scan for what objects are reachable. [there is also the cost of an item being copied internally as it progresses through the generations]"

    Wait what? You have seen code where a reference to a singleton was stored in a field in a class???. That sounds insane.

    3: There is nothing difficult about testing the Singleton class itself. You just call get(), and test it as any other object you want to test. Where you can get problems is that, if you are running multiple tests, they may change the singletons state, so in worst case a test might fail if and only if, an other test have been running before which changed the state of the singleton.

    TheCPUWizard:
    Try writing robust concurrent tests (many tests running at the same time) against a single instance. It is virtually impossible (if the object maintains any state - and if it is stateless, why is it an instance?). Speed of execution is critical for things such as gated check-in testing.

    But that has nothing to do with the singleton pattern. You would have the same problem if you replaced the singleton, with a normal object which would be used by multiple threads.

    If you have a design where your singleton can be replaced by collection of objects(One per thread/object) then you should not use a singeton.

  • (disco) in reply to gnasher729
    gnasher729:
    They don't bother ensuring that only one instance exists through code, but through code reviews.

    That sentence says the same thing if you take off the last six words.

  • (disco) in reply to JBert
    JBert:
    What's with the hate agaist disenvoweled brand names? Don't you know you can never be successful if your brand has more than 6 characters‽

    Slavonic is basically disemvowelled Russian. The Serbs call themselves Srps. Perhaps there is a secret society of Serbs in marketing departments.

  • (disco) in reply to Masaaki_Hosoi
    Masaaki_Hosoi:
    I actually use singletons a lot for game dev in Unity. I frequently have a GameManager or something like that as a singleton class which generally keeps track of overall game state.

    The reason it's a singleton is:

    1.) Because there's no other sane way to do it because Unity is shitty engine enforcing shitty coding practices.

    Also, once again, fuck you Dicksauce.
  • (disco) in reply to riking
    riking:
    notably, ℵ results and 0.π seconds,

    At least someone noticed...

  • (disco) in reply to Tsaukpaetra

    Oh, no no no. I'm not talking about static references to strings. No, static references to things like database connection pools. Because it's easier to use, see?

  • (disco) in reply to Gaska

    I love Unity but.... I actually can't argue with you there.

    Sigh.

  • (disco) in reply to Martin_Tilsted1
    Martin_Tilsted1:
    Unless you have a finalize in the Singleton

    Good idea. But for some reason(s?) the following code compiles fine in C# but doesn't quite word as intended. No idea why ;-)

     
      // for the demo, we need a base class, so we define some generic one 
      class DemoClass { 
        public string stringField; 
        public int intField; 
      } 
     
     
      // All classes to implement IDisposable as per design convention (After all, the team lead is an cs engineer!) 
      class SimpletonDemoClass : IDisposable { 
        static bool disposed;  // one variable for all is sufficient for a Singleton, of course 
     
     
        // we need to stuff some stuff somewhere (see below) 
        // so we use a dictionary (this a fast way to retrieve stored data) 
        // but the dictionary needs a key 
        // and ParamList is the type of that key 
        struct ParamList { 
          string stringField; 
          int intField; 
          int id;  // necessary because we run in trouble when trying to put two different elements with the same keys into a dictionary 
          public ParamList(string stringParam, int intParam, int idParam) { 
            this.stringField = stringParam; 
            this.intField = intParam; 
            this.id = idParam; 
          } 
          // design convention wants all classes to have a destructor, and structs are something like classes too, after all 
          // seemingly they aren't; won't compile 
          /* 
          ~ParamList() { 
            // reset all internal variables 
            this.stringField = string.Empty; 
            this.intField = 0; 
            this.id = 0; 
          } 
           */ 
        } 
     
        // we use a dictionary so we can do a fast search for a key 
        static System.Collections.Generic.Dictionary<ParamList, SimpletonDemoClass> definedStuff; 
     
        private static DemoClass _demoClass; 
        private static SimpletonDemoClass _simpletonDemoClass; 
        public static SimpletonDemoClass getInstance() { return SimpletonDemoClass._simpletonDemoClass; } 
     
     
        public string stringField { 
          get { return _demoClass.stringField; } 
          set { _demoClass.stringField = value; } 
        } 
        public int intField { 
          get { return _demoClass.intField; } 
          set { _demoClass.intField = value; } 
        } 
     
     
        public SimpletonDemoClass(string stringParam, int intParam) { 
          if (_simpletonDemoClass == null) {  
            _demoClass = new DemoClass(); 
            _demoClass.stringField = stringParam; 
            _demoClass.intField = intParam; 
          } else if (_simpletonDemoClass.stringField != stringParam || _simpletonDemoClass.intField != intParam) { 
            // we need an else if here because the constructor could be called with different parameters afterwards 
            // seemingly this* was the cause of trouble when we accessed this class from two different locations 
            // *: not the current instance of this class but the omission of the else if 
            // There is already an instance with different params; so stuff the current instance somewhere and create a new one 
            // if the place to stuff the stuff doesn't exist yet create it 
            if (definedStuff == null) { definedStuff = new System.Collections.Generic.Dictionary<ParamList, SimpletonDemoClass>(); }; 
            // TODO: somewhere around here seems to be the cause of a memory leak; look after it! 
            definedStuff.Add(new ParamList(stringParam, intParam, definedStuff.Count), SimpletonDemoClass.getInstance()); 
            // now search definedStuff whether there's already the thing we need in it 
            bool found=false; 
            foreach(SimpletonDemoClass s in definedStuff.Values){ 
              if (_simpletonDemoClass.stringField == stringParam || _simpletonDemoClass.intField == intParam) { 
                found=true; 
                _simpletonDemoClass = s; // from further down for here s still exists 
                break; 
              } 
            }; 
            if (found) { 
              // _simpletonDemoClass = s; // s doesn't exist here anymore for some unintelligible reason, so I put this a few lines up 
              // no further action required 
            } else { 
              _demoClass = new DemoClass(); 
              _demoClass.stringField = stringParam; 
              _demoClass.intField = intParam; 
            } 
          } else { 
            // no action required, our instance of this singleton already fits the required params 
          }; 
        } 
     
        ~SimpletonDemoClass() { 
          this.Dispose(); 
        } 
     
        #region IDisposable Members 
     
        void IDisposable.Dispose() { 
          if (!disposed) { 
            _demoClass = null; 
            disposed = true; 
          }; 
          throw new NotImplementedException(); // leave this here, just in case 
        } 
        void Dispose() { ((IDisposable) this).Dispose(); } 
     
        void Dispose(bool disposed ) { 
          // throw new NotImplementedException(); 
          if (!disposed) { 
            Dispose(); 
          }; 
        } 
     
        #endregion 
      }
  • (disco) in reply to gnasher729
    gnasher729:
    What I detest is the sneaky way how you try to insult anyone disagreeing with you by calling them "cargo cult followers".

    That was never my intent. However I do stand by the statement as intended. There are cargo-cult programmers [it is discussed often] and I am convinced (based on experience) that the raw number of them far exceeds the quantity of people who have as their primary career function "actively study, publish and utilize Design Pattern based development"

    Apologies if this was taken to offend that many people that are between the two endpoints of this spectrum.

  • (disco)
    Martin_Tilsted1:
    So usage of singletons in large programs should in general be replaced by dependency injections, or simply a hash map which contains named objects with different responsibilities.

    That (along with the rest of the related paragraphs) is a good example of the alternate patterns I have alluded to.

    Martin_Tilsted1:
    Wait what? You have seen code where a reference to a singleton was stored in a field in a class???. That sounds insane.

    More often than I ever care to.

    Martin_Tilsted1:
    But that has nothing to do with the singleton pattern. You would have the same problem if you replaced the singleton, with a normal object which would be used by multiple threads.

    It has everything to do with it. With a "normal object" (publically or even internally constructable) each test would use a different instance.

  • (disco) in reply to Martin_Tilsted1
    Martin_Tilsted1:
    So usage of singletons in large programs should in general be replaced by dependency injections

    Exactly. Code is simpler when you can stop worrying about where the instances come from and focus instead on just using them right. It sounds like a trivial change — heck, it is a trivial change — but it makes a real difference. (Also: the first rule of Fight Club DI Containers is that you don't talk about the DI Container.)

  • (disco) in reply to TheCPUWizard
    TheCPUWizard:
    Show concrete examples of where there is a real world "type" that there should only ever be one instance in the universe

    SupremeDeity supremeDeity = SupremeDeityFactory(thisUniverse).getDeity();

  • (disco) in reply to kupfernigk
    kupfernigk:
    SupremeDeity supremeDeity = SupremeDeityFactory(thisUniverse).getDeity();

    Cute code :smile: that could spark a lot of (non-technical) debates...

    Even so, it is not a Singleton Class being shown :stuck_out_tongue: :stuck_out_tongue: :stuck_out_tongue:

    Finally, there is the presumption that a different universe would/could produce a different instance. This would only make sense if we had actual access to other universe's [you would have nailed me if I said "world" or even "Galaxy"]

    :wave:

  • (disco) in reply to TheCPUWizard

    Quantum Computing, man. Its the future!

    And besides, that's Java. It'd be implemented that way even if you do only have one universe.

  • (disco) in reply to TheCPUWizard
    TheCPUWizard:
    Cute code that could spark a lot of (non-technical) debates...

    Even so, it is not a Singleton Class being shown

    You didn't ask for a Singleton; you asked for a type of which there should only be one instance in the Universe. So I gave you a type of which there should only be one instance in the universe. As far as I can see my answer is literally correct and complies with the specification. Didn't mean that? How many times has someone written a specification and assumed what they got was wrong because it didn't agree with their mental picture of what the result looked like, but which wasn't actually specified. To quote the absolute bottom worst manager I ever worked for, "I'll know it's right when I see it." Mind you, this was also the guy who thought it was "quite easy" for someone else to find a free-to-use icon library to suit his mental picture of what the icons should look like.

  • (disco) in reply to gnasher729

    Singleton classes are a responsibility conflation, as explained upthread. Either you have a free factory function (or a global, if need be, but that is much rarer due to the Static Initialization Order Fiasco -- see cin and cout), or you have an injected dependency; in both cases, there's a seam between the type and the means of creation that allows the means of creation to be replaced without having to modify the using code. A true Singleton violates this because the using code is coupled to the type of the singleton class.

  • (disco) in reply to PWolff
    PWolff:
    design convention wants all classes to have a destructor
    PWolff:
    C#

    Oh my fucking Jesus I'm outta here.

    On one hand I hope this code is a joke, on the other it looks much too insane to be one.

  • (disco) in reply to Magus
    Magus:
    And besides, that's Java. It'd be implemented that way even if you do only have one universe.

    Java being Java, there's several ways and all of them have their own problems (as well as being very verbose). Here's one of the less noxious ones:

    public SupremeDeityProvider getGodProvider() {
        for (SupremeDeityProviderFactory religion :
                ServiceLoader.load(SupremeDeityProviderFactory.class)) {
            try {
                return religion.getGodFactory();
            } catch (Throwable problem) {
                // This is one place where catching Throwable is sensible...
                System.err.print("problem getting god factory from " + religion
                        + ": going to next");
                problem.printStackTrace(System.err);
            }
        }
        System.err.println("no working god factory available");
        System.exit(1);
    }
    

    Sane code delegates this sort of shit to a DI framework like Spring (which is nasty inside, but simplifies your code and that's what you really care about).

  • (disco) in reply to dkf

    Yeah, in C#, I'd typically just do:

    [ImportingConstructor]
    public ThingThatNeedsGod([Import] God god)
    {
      ...
    }
    
  • (disco) in reply to Magus

    Yes, I'd probably do something like this too:

    @Inject public ThingThatNeedsGod(God god) {
       ...
    }
    

    Though I tend to use a slightly more complex version in my code.

  • (disco) in reply to kupfernigk
    kupfernigk:
    You didn't ask for a Singleton

    Context my friend, context :smile: That is also why I made the original comment about sparking debate.

  • (disco) in reply to tarunik
    tarunik:
    Singleton classes are a responsibility conflation, as explained upthread

    Agreed.

  • (disco) in reply to Maciejasjmj
    Maciejasjmj:
    On one hand I hope this code is a joke, on the other it looks much too insane to be one.

    As I'm a German, the joke option is definitively out of scope.

    But it is quite possible that that code is as insane as me. I've been around here for quite a while, and even before that I was a medically approved insane.

    (That code was a somewhat childish attempt to write "believable bad code"® - see http://thedailywtf.com/articles/Classic-WTF-Top-Entries-of-OMGWTF-Part-1

  • (disco) in reply to kupfernigk
    kupfernigk:
    So I gave you a type of which there should only be one instance in the universe. As far as I can see my answer is literally correct and complies with the specification

    https://en.wikipedia.org/wiki/Hindu_deities#Number_of_deities

  • (disco) in reply to Jaloopa
    Jaloopa:
    kupfernigk:
    So I gave you a type of which there should only be one instance in the universe. As far as I can see my answer is literally correct and complies with the specification

    https://en.wikipedia.org/wiki/Hindu_deities#Number_of_deities

    But the type was "SupremeDeity" and according to the Wikipedia page cited ,

    According to Adi Shankara, there is only one supreme Para Brahman, and all of the other deities are its forms and expansions.

    So this is maybe not the right counterexample?

  • (disco) in reply to jkshapiro
    jkshapiro:
    So this is maybe not the right counterexample?

    If there is no Supreme Deity, the factory method should throw an Exception. Whether it's a NullPointerException, a NullDeityException or a NullUniverseException is left as an exercise.

  • (disco) in reply to kupfernigk

    InvalidPantheonException?

  • (disco) in reply to Scarlet_Manuka
    Scarlet_Manuka:
    InvalidPantheonException

    I'd expect this exception only in environments that are atheistic by design.

    Otherwise, I'd expect just an empty instance of Pantheon.

  • (disco) in reply to PWolff

    Perhaps we're not talking about the same thing? I'm talking about the exception that would be thrown by the SupremeDeityFactory class when asked to produce a SupremeDeity object, if there is none applicable. I have the opposite expectation to you, I guess; in an atheistic environment I'd expect this to just return an empty SupremeDeity (or perhaps just hand the request off to a UniverseFactory if the type system permits), but in a polytheistic environment with no supreme deity I'd expect it to throw an exception. (Come to think of it, this might be better presented as a TheGodsAreStillArguingThatQuestionException...)

    Also I may be slightly bored at work today.

  • (disco) in reply to Scarlet_Manuka
    Scarlet_Manuka:
    Come to think of it, this might be better presented as a TheGodsAreStillArguingThatQuestionException

    Well, that would explain the religious nature of the wars between different groups of software enthusiasts – it's an old and therefore venerable tradition.

  • (disco) in reply to Scarlet_Manuka
    Scarlet_Manuka:
    in an atheistic environment I'd expect this to just return an empty SupremeDeity

    That would be wrong. The right thing would be to throw an exception on the grounds that no such entity exists.

    Scarlet_Manuka:
    (Come to think of it, this might be better presented as a TheGodsAreStillArguingThatQuestionException...)

    Either that or just make the method wait until the matter is resolved.

  • (disco) in reply to dkf
    dkf:
    just make the method wait until the matter is resolved

    Give that method an overload with an (uint256) argument maxWait that gives the amount of time after which the method will give up (returning null instead of an empty instance of Pantheon), measured in 2^256 Planck times.

  • (disco) in reply to PWolff
    PWolff:
    returning null instead of an empty instance of Pantheon

    Ouch! Never make new return a null! Let it succeed and return an object or fail and throw an exception.

  • (disco) in reply to dkf
    dkf:
    Ouch! Never make new return a null! Let it succeed and return an object or fail and throw an exception.

    Oops – you're right; I traced the thread a bit upwards. OTOH, this IS TDWTF, after all, so why not return a null? This might actually happen in RL if one coder writes the factory frame, and another one writes the special case handling.

  • (disco) in reply to PWolff
    PWolff:
    OTOH, this IS TDWTF, after all, so why not return a null?

    As you'll know from reading any Richard Dawkins atheism rant, the suggestion that there might be a supreme deity will most definitely make him take exception.

  • (disco) in reply to dkf

    Well, if you start outside logic, you've already made a mistake. The strongest thing logic can get you is 'there may not be a supreme diety'.

  • (disco) in reply to Magus
    Magus:
    Well, if you start outside logic, you've already made a mistake.

    Technically, you start with a set of axioms that you pick for whatever reason you want, and then you use logic to extend from that foundation to a larger set of statements that you accept as true. If you start with excessively wacky axioms (e.g., that the local hospital is made of chocolate hitler figurines) you get locked up as a dangerous lunatic, and if you start with non-consistent axioms then you get very weird behaviour too (as how someone behaves will strongly depend on how they path they chose to reason along).

    The strong atheists start with an axiom that there is no God. It's not something that you can debate with them; they will conclude that you are mistaken rather than that they are wrong. However, it is a feature of the matched pair of axioms that there is/isn't a God that you can socially function perfectly well with either or even without any of them. (As they are directly contradictory, having both is a Bad Idea.) This means that people who prefer minimal axiom sets will avoid saying much about God at all.

  • (disco) in reply to dkf

    Not everyone with a belief about God puts God in their axioms, e.g., Thomists.

  • (disco) in reply to boomzilla

    So they have God-existence as being a derived statement.

  • (disco) in reply to dkf

    Yep

  • (disco) in reply to boomzilla

    e. g.

    https://en.wikipedia.org/wiki/G%C3%B6del%27s_ontological_proof

  • (disco) in reply to PWolff

    Regexes or it didn't happen.

  • (disco) in reply to PWolff

    I always found that a bit of a suspicious argument. There's lots of things I can think of that don't exist, and just because I can think of them doesn't mean that they must exist. Or at least that billion dollars in a bank account in my name, that's doing a very good job of not existing…

Leave a comment on “Patterned After Success”

Log In or post as a guest

Replying to comment #:

« Return to Article