• Gaui (unregistered) in reply to snoofle

    Actually, it should be:

    public static KpiService getInstance() { if(instance == null) instance = new KpiService();

    return instance; }

  • Beta (unregistered)

    A new design pattern: Null Class, when only zero (at most) instances of the class may exist at a time.

  • Jeff Dege (unregistered) in reply to Dave Insurgent
    Dave Insurgent:
    Jeff Dege:
    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?

    The user of the Logger class never sees SingletonManager, or any of its implementing functionality. He just calls Logger.getInstance().

    So whether the functionality is provided by a single multi-purpose class or by a bunch of separate Factory classes is, fundamentally, irrelevant.

  • Dave Insurgent (unregistered) in reply to Jeff Dege

    I appreciate that it is irrelevant to the caller, but we're talking about implementation.

    Logger.getInstance() can make use of a static LoggerFactory which, at least, only concerns itself with the construction of loggers - SingletonManager appears, to me, a violation of both SRP because it is going to contain construction logic for all sorts of things it manages, as well as OCP (okay I may be stretching here) because it requires modification to the SingletonManager whenever you introduce something completely unrelated to the other singletons.

    Either that or it's a useless layer of indirection.

  • wgeek (unregistered) in reply to Dave Insurgent

    Dude, you're over-thinking it to your detriment.

    You ask this question:

    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()).
    And I answer it thusly: if my design goals, which BTW you BLITHELY IGNORE, are such that I want to model that physical aspect of the "world", then YES, I DO IN FACT want the Player to "know" or "have knowledge" of the sound.

    In particular its duration.

    Yes, inter-object communication is a PITA. Decouple it then, as you have stated, with events or some other mechanism that provides a "mediator" as it were in between the Player and the sound.

    Think outside the box man, and always know what the design goals are before trying to apply a so-called solution.

  • wgeek (unregistered) in reply to wgeek

    I would argue that the player SHOULD in fact "know" or better stated, HEAR, the sound of the weapons. This makes stealth missions possible.

    An easy way with no jive indirection, which MAY meet the design goals (as yet, UNSTATED): create a base class "Weapon" with both abstract and concrete implementations of methods.

    Use the "observer" pattern to couple that weapon with the subject, in this case the player.

    Now, use an "Environment" object that will set the parameters such as amplitude and duration of the sound appropriately for the given environment. In fact, some form of class factory would be very useful here.

    Ain't rocket science dude and I honestly think you're way off base with this. ALL WEAPONS make a sound. Think about it. If in a vacuum, the weapon's attributes such as amplitude and duration can simply be zeroed out, without need for a tri-state situation involving nulls, nor funky edge cases.

    Later.

  • (cs) in reply to Dave Insurgent

    The only Singleton-by-rule is the Factory. The Factory maintains a list of instances of Responsible objects. The Responsible objects themselves are Singleton-by-convention- they're basically useless except for one specific task: handling requests. They're stateless because those requests arrive via a web-service. Yes, they maintain configuration information, but configuration is only checked on instantiation.

    The reason to enforce Singleton-by-rule on the Factory is that, again, it's a web service. I don't want to regenerate the Factory's list on every request, since we expect a fairly high number of requests and a high cost for creating at least some of the Handlers. In this case, it's far less developer effort to make the Factory a Singleton versus doing the actually efficient thing and caching it.

    Now, if I actually wanted to dynamically load Handlers by scanning a directory for assemblies, then yes- caching would be superior (it would load new Handlers on every cache expiration). But that would be really premature- the number of handlers is as-yet-unimplemented, but known.

    And as for testability, the configuration is managed by a class itself- something I can inject inside of a unit test.

  • (cs)

    Also: this thread is essentially a textbook on why you can't design an object model without carefully defining your problem domain.

  • Dave Insurgent (unregistered) in reply to wgeek
    Dude, you're over-thinking it to your detriment.

    Aside from the fact that I don't believe I'm over thinking it, because I'm specifically advocating design decisions that are reasonably well established, I don't understand at what point I've suffered harm or loss even if I was over-thinking it.

    You ask this question:

    The following quoted block of text was not a question.

    I want to model that physical aspect of the "world", then YES, I DO IN FACT want the Player to "know" or "have knowledge" of the sound.

    I think you're possibly confused with my use of "know" or "have knowledge" - it's not about being able to percieve the sound as a matter of game logic. It's about the player class, the actual code, being the one responsible for making the call to the sound system, or service, or whatever, to play the sound. The coupling between whatever it is you want a Player object/class to represent, and the fact that sound can be generated, is unwise based on numerous software engineering princples.

    In particular its duration.

    Why did you call this out specifically? You really want the Player instance to store the duration of a particular sound? Each and every sound that the Player may make? For what purpose? If I was right earlier in your confusion, you may mean to keep track of how long a "noise" has been heard, for some game rule calculation. I don't have anything to say about that, because it's all about what you want to do with it.

    I really don't see how bringing up data-driven vs. inheritance to model abstract concepts in a system is over-thinking it, not to mention...

    Decouple it then, as you have stated, with events or some other mechanism that provides a "mediator" as it were in between the Player and the sound.

    After being seemingly critical of what I'm suggesting, you go on to agree with me?

    Think outside the box man, and always know what the design goals are before trying to apply a so-called solution.

    Well, duh - we're talking about abstract concepts and their general application; I don't understand how you object to this. All sorts of discussion happens around the various merits of certain design patterns and other techniques such as dependency injection, without fixing to a specific "design goal" (except that the "design goal" is generally assumed to start with "design software that doesn't suck, which [...]" and there are a number of things that help with that first part.

    Try to avoid global state. Wait, I don't know what your desing goals are.

    I would argue that the player SHOULD in fact "know" or better stated, HEAR, the sound of the weapons. This makes stealth missions possible.

    This is not what we're talking about. We're not talking about the ability for sound that exists in the environment to be detected by other things in that environment. We're talking about the player [i]causing the sound to play directly by a code call as opposed to indirectly by event-driven architecture[i].

    ALL WEAPONS make a sound. Think about it. If in a vacuum, the weapon's attributes such as amplitude and duration can simply be zeroed out, without need for a tri-state situation involving nulls, nor funky edge cases.

    Where is the tri-state null edge case? The weapon shooting emits an event indicating as such. The game engine has various subsystems that observe the event and alter the game accordingly: the rendering subsystem displays a muzzle flash. the audio subsystem plays a "bang". the environmental subsystem alerts nearby enemies. the physics subsystem produces a projectile that causes damage to a crate.

  • Dave Insurgent (unregistered)

    In retrospect, perhaps the confusion, if I'm right about it, was because I talked about "sound" which is possibly ambiguous (although I thought not because we were talking about code) between the sound the player of the game hears in the real world and the sound the Player could hear in the game world. When I say the game object should not "have knowledge of sound" I meant "have knowledge of the audio subsystem used to produce sound in the real world".

  • George (unregistered)

    This is a pattern known as 'the Schizophrenic Singleton'.

  • Hal (unregistered) in reply to snoofle

    True enough. Where ever you go, there you are.

  • (cs) 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).

    Singleton is a class of WTFs, it should be called the Bottleneck pattern. You can easily waste far more cycles waiting for the damned singleton than you would creating a new instance each time.

    Just use thread locals:

    public class Service {
        private final static Service instance = new ThreadLocal<Service>();
        public final static getService() {
            Service inst = instance.get();
            if (inst == null) instance.set(inst = new Service());
            return inst;
        }
    }

    And unless you're an asshole and pass it to another thread, you never have to worry about locking.

  • inhibeo (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 have now resolved to call it the Simpleton pattern.

  • McFly (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!

    Obviously that appears to be the case: a) You have to explicitly call the default constructor (or else getInstance will return null) and b) what is even worse you might choose to call the default constructor anywhere in your code changing the instance in your wake (not so unique is it), leading to inconsistent behaviour or worse.

  • delenit (unregistered) in reply to Slapout
    Slapout:
    @Deprecated:
    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? :-)

    I have made an exception for you. Pray that I do not throw it.

  • Errorsatz (unregistered)

    I've actually seen this type of pattern before, and it does have a legitimate use - although technically it may not qualify as a singleton. Let's say you have an object which there is only one of at a given time, but the object can vary over the course of the program. For example, the player avatar in a game, which could vary from a person to ship to whatever as you go through different levels. Now technically yes, there are different ways you could accomplish this that conform to patterns better.

    However, that brings me to my second point. Games, especially small games, have different requirements from "enterprise" projects. When you're making a game, you're not trying to create every possible design, you're trying to create this design. Trying to make your side-scroller also have the capability to be a FPS, puzzle game, and sandbox - when those aren't part of the design - is more of a liability than a benefit. You're also not (generally) trying to create an engine that will last decades.

    Personally, I've found that trying to anticipate every possible feature leads to a mess of excess code that's harder to maintain, and you still end up missing something. Make the code work for the actual design, and refactor as necessary. And yes, that means that when something is limited to a single instance in the design, it can be a single instance in the code as well.

  • (cs) in reply to Garrison Fiord
    Garrison Fiord:
    Garrison Fiord:
    Over the years I've read from this site, I've read countless comments criticizing the editors. I've read offensive and possibly-illegal posts by Zunesis. I don't know why I'm suddenly being singled out for harassment.
    Fixed. Yes, now I don't contribute, since my comment is going to be deleted anyway. I'm not going to register so you can spam my email address either.
    For the record, I have never been spammed as a result of having registered on this site.
  • (cs) in reply to RandomGuy
    RandomGuy:
    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.
    Reminds me of the sheep in animal farm: "Local variables good! Global variables bad!"
  • wgeek (unregistered) in reply to Dave Insurgent

    What I "object to" as you say, is your blind zeal for all things event driven, presumably your cure-all for all things that may resemble direct coupling.

    And to make your point, you then post a contrived, even ridiculous example that doesn't show coupling per se, it shows INLINING of the sound code in the relevant object.

    You don't bother to even CONSIDER the usage of a base class with virtual methods?

    Events are nothing more than the Observer design pattern, and they come with many shortcomings as opposed to using a more "direct coupled" approach (by way of polymorphism, NOT your naive inlining of code into ridiculously named class methods).

    Blindly advocating an event-driven architecture without stating the features and benefits strikes me as naivete; not good engineering.

    Carry on.

  • wgeek (unregistered) in reply to Errorsatz
    Errorsatz:
    I've actually seen this type of pattern before, and it does have a legitimate use - although technically it may not qualify as a singleton. Let's say you have an object which there is only one of at a given time, but the object can vary over the course of the program. For example, the player avatar in a game, which could vary from a person to ship to whatever as you go through different levels. Now technically yes, there are different ways you could accomplish this that conform to patterns better.

    However, that brings me to my second point. Games, especially small games, have different requirements from "enterprise" projects. When you're making a game, you're not trying to create every possible design, you're trying to create this design. Trying to make your side-scroller also have the capability to be a FPS, puzzle game, and sandbox - when those aren't part of the design - is more of a liability than a benefit. You're also not (generally) trying to create an engine that will last decades.

    Personally, I've found that trying to anticipate every possible feature leads to a mess of excess code that's harder to maintain, and you still end up missing something. Make the code work for the actual design, and refactor as necessary. And yes, that means that when something is limited to a single instance in the design, it can be a single instance in the code as well.

    I concur.

    Event-driven architectures are a pain in the ass to debug.

    The concept of a publisher/subscriber is not readily expressed outside of meta-attributes, and can lead to a whole mess of other issues and very difficult to follow runtime behavior.

    They are great if the goal is to, as you say, allow for future expansion OR dynamic publish/subscribe types of things.

    But if the constraints of the game are in place, pure inheritance type of - GASP - coupling is often the better choice in terms of modelling the intent and ease of debugging.

    Singleton's are legitimate and simple ways to model one instance of an object: such as a printer, a screen, or an ini file. Only one such object can ever exist, and its state is shared. Model it with a Singleton then.

  • Jack Mathews (unregistered)

    Took me a minute to get it too.

    Since the coor is public and there is no verification on setting the instance, any number of these objects can get created and silently become the new global instance.

  • wgeek (unregistered) in reply to QJo
    QJo:
    RandomGuy:
    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.
    Reminds me of the sheep in animal farm: "Local variables good! Global variables bad!"
    Or "Coupling bad"....

    Hey, global scope is global scope if the entire program needs access to it! This happens! Use namespaces for crying out loud: that's why they exist.

    And coupling is not in and of itself bad. It is INFLEXIBLE. But that does not equate to BAD. Even in the enterprise. IF that aspect of the design will not and cannot change, then couple it!

    It will be easier to maintain and debug down the road.

  • (cs) in reply to scooby509
    scooby509:
    Just use thread locals: [...] And unless you're an asshole and pass it to another thread, you never have to worry about locking.
    Good luck doing that with anything that accesses a non-shared resource, like a log file.

    It's called a singleton because there is only one instance of it across the whole application...

  • Randy Snicker (unregistered) in reply to Dave Insurgent
    Dave Insurgent:
    What about Equipment that can only be used once? Is that a Consumable? Or does Consumable imply that the player actually eats it?

    Consumable is a bad name, because you get this sort of problems when people don't agree whether it means something that gets used up, something edible or something that a person stuff down their throats (but possibly shouldn't). You should know whether you're playing with data structures or with game objects.

    Dave Insurgent:
    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>.

    Well, no one told you to be an idiot about it. Inheritance shouldn't be used as a labeling tool for abstract properties. Inheritance should be used to define the methods (and implementations) of use. Programming isn't philosophy, programming is engineering. There shouldn't be a class called Damaging. Instead, you could have a Weapon class defining an interface functions (and possibly subclasses) for different ways of using something as a weapon.

  • linepro (unregistered)

    Aah the simpleton pattern. I remember it well...

  • David (unregistered) in reply to jay
    jay:
    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.

    This is the first comment that Ive fully agreed with.

    Programming is a form of modelling, and the whole point of modelling is to extract and use those properties that are relevant while ignoring those that are not.

    Ignoring relevant properties is as dangerous to the sanity of the code and the programmer as is larding the app with unneccessary cruft purely in order to conform to a particular dogma.

    If your methodology completely forbids a particular structure - GOTOs, global variables, doesnt matter - then the case will one day arise where it is simply wrong.

    And how you deal with that case makes all the difference. Do you accept that every methodology has its limits, and switch codes? Or do you mash the problem until the square edges are ground off and it will, with some hammering, fit through that round hole?

    I suspect (without proof) that more WTFs arise form the second case than the first.

  • Maurizio (unregistered) in reply to Jeff Dege

    And why you need a single SoundManager instance ? Wouldn't make more sense to have SoundManager instances that deals with different kind of events/sounds, depending on the complexity of the application ?

    And once there, wouldn't make sense to do not call it SoundManager, since sound manager is a low level task, while what you want to handle are application events, not sounds as such.

  • (cs) in reply to jay
    jay:
    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."

    I think there is a missing step in this logic: the one where you get from "seems useful" to "is useful".

  • Ahmad Alhaj Hussein (unregistered)

    Using the Enum Singleton are better in Java than double checking Singleton because creation of Enum instance are easy to write and thread-safe ///////Easy Singleton public enum EasySingleton{ INSTANCE; } ///////Complex Singleton public class DoubleCheckedSingleton{ private DoubleCheckedSingleton INSTANCE;
    private DoubleCheckedSingleton(){}

    public DoubleCheckedSingleton getInstance(){ if(INSTANCE == null){ synchronized(DoubleCheckedSingleton.class){ //double checking Singleton instance if(INSTANCE == null){ INSTANCE = new DoubleCheckedSingleton(); } } } return INSTANCE; } }

  • (cs) in reply to Fakeyede Mobolaji

    thx for the info! actually most of us already knew that. we do not come here for solutions, but for wtfs. you just outed yourself a noob. but it's ok. we're all noobs!

  • TheCPUWizard. (unregistered)

    For those discussing the Singleton pattern.... here is a great question (I love to give it on interviews...)...

    How do you determine if a Singleton pattern or a Static class is the appropriate choice for a given situation?

  • CustardCat (unregistered) in reply to snoofle

    Isn't the getInstance() supposed to have some kind of:

    if (instance == null) instance = new KpiService();

    though?

  • CustardCat (unregistered)

    Oop!

    Caught out by the Featured Comments thing again..

  • Jack (unregistered) in reply to snoofle

    What's wrong is that the singleton implementation depends on some code somewhere calling the object constructor first to establish the static singleton. And if any code anywhere else calls the constructor the global singleton value is changed. So, the value of the singleton is unpredictable and possible not present. While this may work and you may get away with it, it will eventually bite you in the butt.

  • (cs) in reply to glopal
    glopal:
    The getInstance method should instantiate the instance variable using the constructor, which should be private. No?
    No.

    If you create the instance when the getInstance() method is invoked, you need to make sure that it wasn't initialised before. And because of thread-safety, the check must be put in a 'synchronized' block, which synchronises against the singleton's class object. That's an expensive operation in terms of CPU time.

    In other words, the instance should be created statically, which in Java means it still gets constructed only when accessed for the first time.

  • (cs) in reply to TheSHEEEP
    TheSHEEEP:
    The question is not why I would want to allow something, the question is why would I want to limit something that does no harm?

    [...]

    I am absolutely convinced that a simple SoundManager singleton would be far easier to understand than the complex architecture you suggest. And it would also be much faster, an event system would simply introduce clutter.

    [...]

    I get the idea, but that would be an overly complex solution to a very easy problem. You know, we have a nice saying in our office: "You can solve any problem by adding another layer of indirection. Except too many levels of indirection." Some people should really take that to heart. ;)

    The problem is that you're confusing ease and simplicity. They're not the same thing. The solution you've chosen is the easiest, but not necessarily the simplest - simplest in terms of transparency, maintainability, and all the other things that are a factor in software development.

    A singleton is a global variable - no more, no less. There are certain things that can't really be solved in a different way than using a static/global/singleton, but if you use it as some sort of magic bullet, you're probably going to, at some point or other, run into the same problems that global variables have caused over the past decades.

    TheSHEEEP:
    Also, people seem to be stuck on that sound example. Let's introduce another one: Logging. In the same game (and in all other applications I wrote and most I encountered) I had a Logging singleton class. Now Logging is really something you want to do from possibly everywhere without having to rewrite your class hierarchy/structure.

    And the possibility to do so from everywhere also doesn't break or harm anything. Except threaded stuff, but you can always make that Singleton thread-safe.

    I find myself passing instances of (log4j) Logger objects around, because of the way that support can dynamically set the location of configuration files, including the log4j.properties file. There's no neat way around that.

    But the point that people are trying to make is that your design may suck, pardon my French. Maybe it's set up in such a way that you don't have an application context, or some other way to access the sound system.

  • Zecc (unregistered) in reply to Beta
    Beta:
    A new design pattern: Null Class, when only zero (at most) instances of the class may exist at a time.
    I use this pattern all the time. The best thing about it is, I don't even need to be write code to implement it.
  • (cs) in reply to wgeek

    And you provided a fine proof why singletons are such a WTF: You will use them in situations where they are not appropriate.

    wgeek:
    Singleton's are legitimate and simple ways to model one instance of an object: such as a printer, a screen, or an ini file. Only one such object can ever exist, and its state is shared. Model it with a Singleton then.
    At my workplace two displays are connected to my PC. Even the simple notepad accessory allows me to select the printer to which i want to print (and lists several printers including a fax-printer and a "virtual printer" which creates a PDF-file).

    And why should there by only one ini file per application?

    At least there should be a separation between global settings and user settings.

    In exactly NONE of your examples a singleton was a good design choice.

  • (cs) in reply to jay
    jay:
    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.

    The point we're trying to make is that you shouldn't be needing the timezone or user preferences in 1000 places. ;) You don't want worker modules knowing directly about where that data is coming from. You want to pass it in so that, for example, if you need the identical functionality with custom inputs you can simply change what you pass to them. If you do decide to cheat and use globals in this fashion then I would prefer you to wrap it up in a factory to hide it from the code (i.e., pass global parameters into the object's constructor with a factory).

  • Bernie The Bernie (unregistered)

    Oh, that type of Singleton is actually a RefreshableSingleton (TM). Whenever your Singleton grew old and bad, just call the constructor, and get a fresh one! Only too bad that the Gang of Four forgot to describe it among their "design patterns". But now you know it, and you'll love to use it.

  • Dave Insurgent (unregistered)
    Games, especially small games, have different requirements from "enterprise" projects.

    Not disputing that. My original comment specifically called out professional games, and I also started out with declaring that I'm not a professional game developer, meaning I was trying to say "Hey, so I heard of this, and it sounds really neat because it solves this problem that experts in the field say comes up very frequently and I hadn't even thought of it that way before until I read it. Maybe you would enjoy it too" - and the poster I replied to, in fact, did. So there's that.

    and refactor as necessary

    Do you agree or disagree that certain up-front decisions may impact that ability to do that? The experience of the leading minds in our field seem to be, for the most part, a collective "yes" - I base this on the scientific aspect of the field as well as the publications of many authors.

    is your blind zeal for all things event driven

    "blind zeal" is a bit much, don't you think? You're basing that on a few comments I made that are all specific to game engine design, in which I led them with a statement indicating that I was not a professional, but had seen a few professional discussions about some problems in game engine design and an interesting alternative approach. I could just as easily call you a "blind zealot" of object-oriented design. What good is that to the discussion?

    it shows INLINING of the sound code in the relevant object.

    That was how it was brought up. The discussion, if you cared to follow it before bringing your loaded gun to the comment box, was:

    • Singletons should be generally avoided [except where experience/need proves otherwise: which is a caveat in every freaking guideline that you seem to want spelled out each time otherwise it is 'zeal']

    • I used a Singleton here, because I needed to call it

    • Do you think that your class should call that Singleton directly? Since there will be many classes that would call that Singleton, there may be a way to break that specific part down in to some other reusable component. With the - seemingly reasonable - assmumption that most of us here are aleady object-oriented developers, I'd like to also highlight some ways that the object-oriented paradigm can fall short, I learned about this not by experience, which I'm basically sorry to say, but by reading about the experience of others who work in the field.

    • How dare you have such zeal as to advocate for an alternate programming paradigm? There is no data-driven, there is no responsibility-driven, there is only Zuul, I mean, object-oriented!

    Events are nothing more than the Observer design pattern, and they come with many shortcomings as opposed to using a more "direct coupled" approach

    They have inverse ownership of the observation, meanign that the item being observed doesn't have to maintain a list. They're obviously different, although I agree that share semantic qualities. What the hell is your point? You gave me shit for not listing pros/cons, but you just said "many shortcomings" without elaborating. I at least pointed out that if the weapon/whatever is responsible for playing sounds, then you have to ensure that behaviour everywhere as a separate act of maintenence, and re-using it via inheritance will likely lead to a bloated, confusing, if not impossible object hierarchy.

    The eventing was an auxillary point, the main point was that having the Weapon know about the SoundManager is an unwise coupling. That wasn't "all coupling is bad, rah!" - and the jump wasn't from "it is coupling, therefore it is bad", it was "it is coupling, and it seems unnecessary, therefore it may be bad".

    (by way of polymorphism, NOT your naive inlining of code into ridiculously named class methods)

    I think you meant to type "separation of responsibilty and data in to meaningful elements by approaching the problem using a different paradigm for the sake of discussion" - it's alright, the keys are like right next to each other.

    Programming isn't philosophy, programming is engineering.

    Well, engineering is a branch of philosophy, just like science. I'd argue the difference is that engineering has little to no tolerance for experimentation, which belongs in science and then gets merged in to engineering after sufficient testing/examination. What's the point? You still use philosophy to practice engineering. Just a refined subset of it.

    There shouldn't be a class called Damaging

    Why not? You don't know my problem domain any better than I know yours. I'm postulating ways to define a robust language for expressing many different configurations that could happen within a game engine. Not a specific application (a game), but the engine - which I'd like to reuse if possible, because I don't like rewriting the same crap every day.

    I like the idea of their being a Damaging attribute (it might not be an actual class definition either: it could be a name of a composite definition of other attributes, but that's not important right now). A Weapon is Damaging. Is a Thruster? I can apply the Damaging attribute to both, so that when the Thruster engages, anybody behind them gets burnt.

    We're not arguing about class naming conventions or object hierarchy, because I get what you're trying to do and it works when it works and it doesn't when it doesn't. I'm illustating that there is a different paradigm for how you model the problem - and that, based on the experience of some professionals, solves some issues that crop up in a neat way.

    Instead, you could have a Weapon class defining an interface functions (and possibly subclasses) for different ways of using something as a weapon.

    I already addressed that point: It works for simple games, but my point was that as games increase in complexity then seem to run in to an awful mess of an inheritance tree, and sometimes end up not being able to model certain things at all.

    You can read more about it here which has aggregated a number of sources on the subject.

  • AGray (unregistered)

    Easy folks! Dave there was just saying that instead of building RPG Items around inheritance, there's an alternative. After sleeping on it, I may or may not agree with all of it, but, hey. I was always told,

    [quote="Generic Programming Professor"]"If you find just one way to solve a programming problem, it's proof you didn't think hard enough."[/quote]

    As far as game settings are concerned, I took a long careful look at my code last night. Using a singleton and using a Settings class instance that starts up immediately when the game does and hangs around in the background offer absolutely no difference; given that I only want one settings repository, though, it's a case where a singleton does wind up making sense. I don't need a plethora of Settings repositories hanging around all over the place.

    The reason that having a repository remains desirable to my project, as opposed to having the game objects themselves host the values directly, is that one scene's Maestro and PlayerControl scripts are discarded across scene boundaries by necessity; while these can be preserved across scene boundaries, it's a prohibitive level of work to do that effectively. The effort just outweighs the rewards. It means I have coupling going on, but honestly? I'm not put off by that. As you'll see below, I've devised some 'unit tests' that take advantage of that.

    How the repository is being defined in this case does not matter, and will honestly not make the code any easier or harder to test; a Unit Test will have a hard time determining whether sound for a GUI element click or background music really is softer or louder...after all, internally, those volume levels are all floats; the unit test at best can only see that the Maestro is correctly conveying the settings to the AudioSource that the Maestro is attached to, but other than that, a user has to manually listen while manipulating settings and mentally ask themselves, "When I slid the Master Volume slider 'downwards', did all sounds become quieter?"

    If I absolutely need to perform a Unit Test in the background, the Unity game engine provides me more difficulty than the Singleton actually does. I'll have to make a test scene that runs my unit tests, for starters - no NUnit for me! :( However, my unit tests will flow somewhat like this:

    [code][Setup] Create new SettingsGUI instance.

    [Test] Set Settings.MasterVolume = (value) Perform synchronization action from instance of SettingsGUI. Does AudioListener.volume = Settings.MasterVolume? (P/F)

    [Test] Set Perform graphics quality action from instance of Settings GUI. Does QualitySettings.level = Settings.graphicsLevel? (P/F)[/quote]

    ...and so on. Actually, in some ways, given Unity's quirkiness...a Unit Test with this singleton isn't too hard to pull off, given that it's acting as a repository.

    So, I agree that testability matters - I have means to create a form of unit testing. I can tie [action] to [business rule].

    I agree that portability matters. I can take my code, apply the Settings GUI to another project, bring over the Settings repository, Maestro, Player Control scripts, and/or even other GUIs, and this stuff will still work with minimal modifications.

    On the other hand, I still agree about multiprocessing and multithreading. I stand behind what was said yesterday: singletons are not threadsafe, and have a small window for a race condition to occur. That being said, that's also not how I'm using this Settings construct. YAGNI still applies!

    (Rest assured though, I do not defend using a Singleton in such an environment; it's the wrong tool for the job.)

    I like this discussion, since it's forcing me not just to justify my design decisions to other people (and yes, I too carefully considered/designed the use of singletons in my project before implementing,) but also to myself. I am a younger programmer (probably obvious), but one thing that is clear to me, is at the end of an implementation, I have to ask myself, "am I comfortable with this? Is this obviously inferior to the alternatives that I have been made aware of?"

    In the case of the Settings? The answer turns out to be 'no,' in the context of my current techniques and the limitations of the engine I'm using, and the bounds of my problem domain (create a JRPG, not a game engine sitting atop a game engine.)

  • Sten (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!

    Wrong is that getInstance() should create the singleton if it does not exist and that the singleton should not be created by anything else which it obviously is

  • danielkzu (unregistered)

    That's pretty much how lots of "ambient singletons" work (i.e. Transaction.Current, HttpContext.Current, etc.).

    There's nothing wrong with the approach.

  • Guardia (unregistered) in reply to szeryf
    szeryf:
    It's wrong because the return statement isn't properly commented. There, I fixed it:
        public static KpiService getInstance() {
            // That's this.
            return instance;
        }
    

    Your comment needed some work.

  • jay (unregistered) in reply to xtremezone
    xtremezone:
    jay:
    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.

    The point we're trying to make is that you shouldn't be needing the timezone or user preferences in 1000 places. ;) You don't want worker modules knowing directly about where that data is coming from. You want to pass it in so that, for example, if you need the identical functionality with custom inputs you can simply change what you pass to them. If you do decide to cheat and use globals in this fashion then I would prefer you to wrap it up in a factory to hide it from the code (i.e., pass global parameters into the object's constructor with a factory).

    Wow, I never thought I'd be defending global data. Usually I have to explain to people why it's bad.

    But for the case where it's good: Let's take a concrete example. Suppose we allow the user to select whether he wants large icons or small icons in his menu bars. We have a preferences screen where he can select this, and we save it from run to run.

    Yes, we COULD say that at start-up time we call a "load preferences" function that reads the preferences and returns, presumably among many other things, the large icon vs small icon indicator. Then we could pass this indicator to every function that paints a screen. Of course we'd also have to pass it to every function that calls a function that paints a screen. I think you can easily see that we would be passing this indicator around everywhere.

    Why? What is gained by doing this? It just clutters up our parameter lists. The whole idea of a preference like this is that it applies everywhere: we're not going to draw screen A with large icons and screen B with small icons. We WANT the icon preference to have only one value everywhere in the system.

    What if function A does not paint a screen today, so I don't pass in the parameter. Then someone comes along and modifies it so now it does paint a screen. Now he has to not only add this parameter to function A, but to every function that calls function A, and to every function that calls one of those functions, etc.

    If this was the only "applies all over the place" data in the system, it might not be a big deal: one extra parameter on every call. But in real life we could have many such things. Are we going to add twenty parameters to every function call? I suppose we could create an "applies all over the place" object and put all these things in there, and then pass this object around. But then all we've accomplished is to do a bunch of extra work to simulate global data.

    Let me make clear that there is a very narrow set of things that are rightly global data, namely, data that applies all over the system, and if it is changed, we want that new value to be used all over the system.

    Of course MOST data that a function uses is only applicable in this specific place. I've written elsewhere about the horrors of global data.

  • Dave Insurgent (unregistered) in reply to jay
    Are we going to add twenty parameters to every function call?

    Well, this is why separation of concerns gets so much attention: What function are you imaginging that has so many responsibilities that it needs twenty parameters of various things?

    Your WindowManager might have an IconFactory that can be used to create an Icon. There are two implementations of the IconFactory: LargeIconFactory and SmallIconFactory.

    Now, odds are the WindowManager wouldn't directly be responsible for the creation if Icons, but rather some kind of Pane or View or Control, the reason being is that Icons aren't necessarily a guaranteed part of the UI. Maybe you want just a flat list - but in creating the [Foo] that places Icons on the screen, you would supply the IconFactory to it.

    I think one important thing to consider is that classes are no different than closures in that they both provide calling context to a function, which means that context around a function call beyond the parameters list isn't "wrng" and so the issue isn't that global state surrounds a function call with extraneous context. That context, if mutable/stateful, provides it's own problems, but there are ways of dealing with that. The anti-singleton crew gets most of its juice from the kind of examples of narrow-sightedness that people like wgeek pose: Hey, there's only one display. Is there? Not on my machine.

    we could create an "applies all over the place" object and put all these things in there,

    Right, which means things go the route of some kind of ApplicationContext. That's not so bad, but the key thing is that you can have more than one. With the Singleton, the very definition of what an ApplicationContext is becomes bound to the notion that there is only one.

    Now, the pragmatic side of the issue is that you shouldn't go putting a bunch of stuff in to satisfy requirements that are undefined. The experienced side knows that this is true, but those same requirements are prone to change and there are reasonable ways of anticipating that change.

    Global, there-can-only-be-one, kind of state is one of those things that hardline pragmatical people say, "fuck it, I'll fix it when I have to" and the leaders of the field say "that's more likely than not, so why not do it differently if there are no other consequences?"

    This may upset a few people but I would frame the issue this way:

    Foo.doSomething() {
        Bar.getInstance().doSomethingElse()
    }
    

    is both a dependency on the use of Bar as well as directly knowledge of how a Bar is constructed, not really different than new Bar().doSomethingElse() except that the convention implies that there's only one Bar, ever.

    The fact that a Bar is constructed somehow is implicit:

    Foo.doSomething(bar) {
        bar.doSomethingElse()
    }
    

    or

    Foo.doSomething() {
      this.bar.doSomethingElse()
    }
    

    both use a bar that exists - but don't need to know how it came in to existence. Bar would possibly be provided as part of the Foo constructor (or via a setter), and we Know This Is Good because of the DIP part of SOLID.

    Obviously there are simpler components that don't need to be lifecycle managed, no one objects to new String() or whatever, and I don't think it's just primitives. The point is that anything you're trying to define as unique, there can only be one, probably has a little more to it than the time. In fact, Calendar isn't a singleton - it's a static factory. I don't see why TimeZone needs to be either.

  • djd (unregistered)

    The problem here (I think, I haven't been doing C++ very long) is that getInstance is static meaning it can be invoked BEFORE any instance is actually constructed, at which point it will return null.

    Is the intent to allow access of the singleton without needing to use its name? Even if that didn't create a bug, why would it be useful?

  • Flo (unregistered) in reply to snoofle

    The problem is that the object is instanciated in the constructor. But the classic way to get a singleton is to invoke the static method getInstance(). You never invoke the constructor (because you never directly create new objects. It is one aim of the singleton pattern...). So at the first invocation of getInstance(), instance is null. And it remains null, unless somebody invokes new()... That is obvious, but it took me a certain amount of time to see where the problem was, because it is so crazy! This is a real WTF!

Leave a comment on “The Lone Rangers”

Log In or post as a guest

Replying to comment #:

« Return to Article