Good case for Singletons?

后端 未结 10 1593
臣服心动
臣服心动 2021-01-05 07:24

I have an application that has several classes used for storing application-wide settings (locations of resources, user settings, and such). Right now these classes are just

相关标签:
10条回答
  • 2021-01-05 07:44

    I think you no need to create signleton class. just make this class constructor private. Like Math class in java.

    public final class Math {
    
        /**
         * Don't let anyone instantiate this class.
         */
        private Math() {}
    
    //static fields and methods
    
    }
    
    0 讨论(0)
  • 2021-01-05 07:45

    Effective Java says:

    Singletons typically represent some system component that is intrinsically unique, such as a video display or file system.

    So if your component warrants single instance across the entire application and it has some state, it makes sense to make it a singleton.

    (The above nakedly borrowed from naikus)

    In many cases the above situation can be handled by a 'utility class' in which all the methods are static. But sometimes a Singleton is still preferred.

    The main reason for advocating a Singleton over a Static Utility Class is when there is a non-negligible cost involved in setting it up. For example if your class represents the file system, it will take some initialization, which can be put in the constructor of a Singleton but for a Static Utility Class will have to be called in the Static Initializer. If some executions of your app might never access the file system then with a Static Utility Class you have still paid the cost of initializing it , even though you don't need it. With a Singleton if you never need to instantiate it you never call the initialization code.

    Having said all that, Singleton is almost certainly the most-overused design pattern.

    0 讨论(0)
  • 2021-01-05 07:49

    Sometimes what people think belong as Singleton objects really can be private members of a class. Other times they should be unique global variables. Depends on what the design needs them to be.

    If there should be one, and exactly one instance of an object: use a Singleton. By that, I mean if the program should HALT if there's more than one object. A good example is if you're designing a video game that only supports rendering to a single output device, ever. Trying to opening the same device again (shame on you for hardcoding!) would be forbidden. IMHO a case like that often means you shouldn't be using classes in the first place. Even C allows you to trivially encapsulating such a problem without the complexity of making a Singleton class, and still maintain the elements of OO that apply to a singleton. When you're stuck in a language like Java/C# , the singleton pattern is what you've got to work with, unless purely static members will do the trick on their own. You can still simulate the other way through those.

    If it's merely a case of interfacing objects, you probably should think more object oriented. Here's another example: let's say our game engines rendering code needs to interface resource and input managers, so it can do it's job. You could make those singletons and do sth like ResourceManager.getInstance().getResource(name). Or you could create an application class (e.g. GameEngine) that has ResourceManager and InputManager as private members. Then have the GameEngine pass these as necessary to methods of the rendering code. Such as r.render(resourcemanager);.

    For singletons—can easily be accessed from anywhere, it's like a global variable, but there can only be one copy of it.

    Against singletons—many uses of singletons can be solved by encapsulating it within in a parent object and passing a member object to another member objects methods.

    Sometimes just using a stupid global variable is the right thing. Like using GOTO or a compounded (and/or) conditional statement instead of writing the same error handling code N times with copy and paste.


    Code smarter, not harder.

    0 讨论(0)
  • 2021-01-05 07:51

    Singletons often show up in situations like you're describing- you have some sort of global data that needs to live in some place, and you'll only ever need one, preferably you want to make sure that you can only have one.

    The simplest thing you can do is a static variable:

    public class Globals{
       public static final int ACONSTANT=1;
    

    This is fine, and ensures that you'll have only one, and you have no instantiation issues. The main downside, of course, is that it's often inconvenient to have your data baked in. It also runs into loading issue if, for example, your string is actually built, by, say, building something from an outside resource (there's also a gotcha with primitives - if your static final is an int, say, classes that depend on it compile it inline, which means that recompiling your constants may not replace the constants in the app - e.g., given public class B{ int i = Globals.ACONSTANT; } changing Globals.ACONSTANT and recompiling only Globals will leave B.i still =1.)

    Building your own singleton is the next simplest thing to do, and is often fine (though look up discussions on problems inherent in singleton loading, e.g. double-checked locking). These sorts of issues are a big reason why many apps are built using Spring, Guice, or some other framework that manages resource loading.

    So basically: Statics

    • Good: easy to code, code is clear and simple
    • bad: Not configurable- you've got to recompile to change your values, may not be workable if your global data requires complex initialization

    Singletons fix some of this, Dependency Injection frameworks fix and simplify some of the issues involved in singleton loading.

    0 讨论(0)
  • 2021-01-05 07:54

    If you don't ever need to instantiate them, I don't see the point of singletons. Well, I should amend that - if these classes cannot be instantiated, then it doesn't make sense to compare them to singletons - the singleton pattern restricts instantiation to one object, and comparing that to something that cannot be instantiated doesn't make sense.

    I find my main use of singletons generally involves a class that has static methods that, after maybe preparing an environment, instantiate an instance of themselves. By utilising private constructors and overriding Object.clone() to throw CloneNotSupportedException, no other classes can create a new instance of it, or if they're ever passed an instance of it, they cannot clone it.

    I guess I'd say that if your application settings are part of a class that is never instantiated, it's not relevant to say "It should/shouldn't be a singleton."

    0 讨论(0)
  • 2021-01-05 07:55

    Singleton will give you an object reference, that you can use all over your app... you will use singleton if you want objects and/or polymorphism...

    0 讨论(0)
提交回复
热议问题