当我同意其他答案时,OP询问为什么不使用具有所有静态方法的类(可能具有静态字段),而不是拥有一个实例的单例。
为什么使用单身人士?
您可以通过Google“单身人士”找到各种原因。从JavaWorld:
有时候,只需要一个类的实例是合适的:窗口管理器,打印后台处理程序和文件系统是典型的示例。通常,那些类型的对象(称为单例对象)可以被整个软件系统中的不同对象访问,因此需要全局访问点。当然,只要您确定自己永远不需要一个以上的实例,那么您便会改变主意。
为什么要使用Singleton而不是所有静态方法的类?
几个原因
- 您可以使用继承
- 您可以使用界面
- 它使对单例类本身的单元测试变得更容易
- 这样就可以对依赖于单例的代码进行单元测试
对于#3,如果您的Singleton是一个数据库连接池,则要确保您的应用程序只有一个实例,但是要对数据库连接池本身进行单元测试,而不会影响数据库(可能使用package-
scope构造函数或static创建方法):
public class DatabaseConnectionPool { private static class SingletonHolder { public static DatabaseConnectionPool instance = new DatabaseConnectionPool( new MySqlStatementSupplier()); } private final Supplier<Statement> statementSupplier; private DatabaseConnectionPool(Supplier<Statement> statementSupplier) { this.statementSupplier = statementSupplier; } static DatabaseConnectionPool createInstanceForTest(Supplier<Statement> s) { return new DatabaseConnectionPool(s); } public static DatabaseConnectionPool getInstance() { return SingletonHolder.instance; } // more pre here}
(注意使用Initialization on Demand
Holder模式)
然后,您可以
DatabaseConnectionPool使用package-scope
createInstanceForTest方法对进行测试。
但是请注意,使用静态
getInstance()方法会导致“静态粘连”,其中依赖您单例的代码无法进行单元测试。
因此,通常不认为静态单例是一个好习惯
(请参阅此博客文章)
相反,您可以使用像Spring或Guice这样的依赖注入框架来确保您的类在生产中只有一个实例,同时仍然允许使用该类的代码可测试。由于Singleton中的方法不是静态的,因此可以使用JMock这样的模拟框架在测试中模拟您的Singleton。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)