Why Singletons are Evil

本文转自:http://blogs.msdn.com/b/scottdensmore/archive/2004/05/25/140827.aspx

While I did not write this, I totally agree with it. Brian Button is probably one of the most talented people I know, and I am sure he would love your feedback.

1)       Singletons frequently are used to provide a global access point for some service.
True, they do this, but at what cost? They provide a well-known point of access to some service in your application so that you don't have to pass around a reference to that service. How is that different from a global variable? (remember, globals are bad, right???) What ends up happening is that the dependencies in your design are hidden inside the code, and not visible by examining the interfaces of your classes and methods. You have to inspect the code to understand exactly what other objects your class uses. This is less clear than it could be. The urge to create something as a global to avoid passing it around is a smell in your design; it is not a feature of globals/singletons. If you examine your design more closely, you can almost always come up with a design that it is better and does not have to pass around tramp data to every object and method.

2)       Singletons allow you to limit creation of your objects.
This is true, but now you are mixing two different responsibilities into the same class, which is a violation of the Single Responsibility Principle. A class should not care whether or not it is a singleton. It should be concerned with its business responsibilities only. If you want to limit the ability to instantiate some class, create a factory or builder object that encapsulates creation, and in there, limit creation as you wish. Now the responsibilities of creation are partitioned away from the responsibilities of the business entity.

3)       Singletons promote tight coupling between classes
One of the underlying properties that makes code testable is that it is loosely coupled to its surroundings. This property allows you to substitute alternate implementations for collaborators during testing to achieve specific testing goals (think mock objects). Singletons tightly couple you to the exact type of the singleton object, removing the opportunity to use polymorphism to substitute an alternative. A better alternative, as discussed in the first point above, is to alter your design to allow you to pass references to objects to your classes and methods, which will reduce the coupling issues described above.

4)       Singletons carry state with them that last as long as the program lasts
Persistent state is the enemy of unit testing. One of the things that makes unit testing effective is that each test has to be independent of all the others. If this is not true, then the order in which the tests run affects the outcome of the tests. This can lead to cases where tests fail when they shouldn't, and even worse, it can lead to tests that pass just because of the order in which they were run. This can hide bugs and is evil. Avoiding static variables is a good way to prevent state from being carried from test to test. Singletons, by their very nature, depend on an instance that is held in a static variable. This is an invitation for test-dependence. Avoid this by passing references to objects to your classes and methods.

I hope this explains a little more fully my opinion of the singleton pattern. I have a small collection of links I found through Google of others, including Jim Hyslop and Herb Sutter, who share this opinion. Let me know if you'd like them.


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
这个异常的原因是在容器销毁阶段时,不允许创建单例的bean。这可能发生在以下情况下: 1. 当一个bean的销毁方法中请求从BeanFactory获取另一个bean时,会触发这个异常。这是因为在销毁阶段,容器已经开始销毁所有的单例bean,此时不允许再创建其他的单例bean。 [2] 2. 这个问题可能是由于容器的生命周期与bean的生命周期不一致导致的。当单例bean在创建时,容器已经处于销毁阶段,这样就无法再次创建该bean。 为了解决这个问题,可以考虑以下几种方法: 1. 检查你的代码,确保在销毁方法中没有请求BeanFactory获取其他bean的操作。如果有这样的操作,可以尝试将其移动到其他地方,或者使用ApplicationContext而不是BeanFactory来获取bean。 2. 确保你的bean的生命周期与容器的生命周期一致。在销毁bean之前,确保容器已经完成了所有的单例bean的销毁操作。 3. 如果你的代码中有多个线程同时启动和销毁bean,可以考虑使用同步机制来确保在销毁阶段不会有新的单例bean被创建。 总结一下,当出现"Singleton bean creation not allowed while singletons of this factory are in destruction"异常时,应该检查代码中是否有在销毁方法中请求BeanFactory获取其他bean的操作,并确保bean的生命周期与容器的生命周期一致。<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [spring启动错误Singleton bean creation not allowed while the singletons of this factory are in...](https://blog.csdn.net/chenwiehuang/article/details/101532591)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [解决Singleton bean creation not allowed while singletons of this factory are in destruction (Do not ...](https://blog.csdn.net/qq_33333654/article/details/103434761)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值