Are there any viable alternatives to the GOF Singleton Pattern?

后端 未结 16 1463
佛祖请我去吃肉
佛祖请我去吃肉 2020-11-29 16:58

Let\'s face it. The Singleton Pattern is highly controversial topic with hordes programmers on both sides of the fence. There are those who feel like the Singleto

相关标签:
16条回答
  • 2020-11-29 17:33

    The finest solution I have came across is using the factory pattern to construct instances of your classes. Using the pattern, you can assure that there is only one instance of a class that is shared among the objects that use it.

    I though it would be complicated to manage, but after reading this blog post "Where Have All the Singletons Gone?", it seems so natural. And as an aside, it helps a lot with isolating your unit tests.

    In summary, what you need to do? Whenever an object depends on another, it will receive an instance of it only through its constructor (no new keyword in your class).

    class NeedyClass {
    
        private ExSingletonClass exSingleton;
    
        public NeedyClass(ExSingletonClass exSingleton){
            this.exSingleton = exSingleton;
        }
    
        // Here goes some code that uses the exSingleton object
    }
    

    And then, the factory.

    class FactoryOfNeedy {
    
        private ExSingletonClass exSingleton;
    
        public FactoryOfNeedy() {
            this.exSingleton = new ExSingletonClass();
        }
    
        public NeedyClass buildNeedy() {
            return new NeedyClass(this.exSingleton);
        }
    }
    

    As you will instantiate your factory only once, there will be a single instantiation of exSingleton. Every time you call buildNeedy, the new instance of NeedyClass will be bundled with exSingleton.

    I hope this helps. Please point out any mistakes.

    0 讨论(0)
  • 2020-11-29 17:34

    Alex Miller in "Patterns I Hate" quotes the following:

    "When a singleton seems like the answer, I find it is often wiser to:

    1. Create an interface and a default implementation of your singleton
    2. Construct a single instance of your default implementation at the “top” of your system. This might be in a Spring config, or in code, or defined in a variety of ways depending on your system.
    3. Pass the single instance into each component that needs it (dependency injection)
    0 讨论(0)
  • 2020-11-29 17:37

    Personally for me а much more sensible way to implement something that behaves like singleton is to use fully static class(static members , static methods , static properties). Most of the time I implement it in this way (I can not think of any behaviour differences from user point of view)

    0 讨论(0)
  • 2020-11-29 17:39

    To understand the proper way to workaround Singletons, you need to understand what is wrong with Singletons (and global state in general):

    Singletons hide dependencies.

    Why is that important?

    Because If you hide the dependencies you tend to lose track of the amount of coupling.

    You might argue that

    void purchaseLaptop(String creditCardNumber, int price){
      CreditCardProcessor.getInstance().debit(creditCardNumber, amount);
      Cart.getInstance().addLaptop();
    }
    

    is simpler than

    void purchaseLaptop(CreditCardProcessor creditCardProcessor, Cart cart, 
                        String creditCardNumber, int price){
      creditCardProcessor.debit(creditCardNumber, amount);
      cart.addLaptop();
    }
    

    but at least the second API makes it clear exactly what the method's collaborators are.

    So the way to workaround Singletons is not to use static variables or service-locators, but to change the Singleton-classes into instances, which are instantiated in the scope where they make sense and injected into the components and methods that need them. You might use a IoC-framework to handle this, or you might do it manually, but the important thing is to get rid of your global state and make the dependencies and collaborations explicit.

    0 讨论(0)
  • 2020-11-29 17:39

    Use a plain object and a factory object. The factory is responsible for policing the instance and the plain object details only with the configuration information (it contains for example) and behaviour.

    0 讨论(0)
  • 2020-11-29 17:39

    I think the best place to police the singleton is at the class design level. At this stage, you should be able to map out the interactions between classes and see if something absolutely, definitely requires that only 1 instance of this class is ever in existence at any time of the applications life.

    If that is the case, then you have a singleton. If you are throwing singletons in as a convenience during coding then you should really be revisiting your design and also stop coding said singletons :)

    And yes, 'police' is the word I meant here rather than 'avoid'. The singleton isn't something to be avoided (in the same way that goto and global variables aren't something to be avoided). Instead, you should be monitoring it's use and ensuring that it is the best method to get what you want done effectively.

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