jSingleton 应该替换为单个或多个接口。这到底是什么意思?
jSingleton should be replaced with single or multiple interfaces. What does this actually mean?
我看到一篇关于 TDD 的文章,其中作者提到 Singleton 是一种反模式,为了避免这种情况,一个解决方案是应该将 Singleton 替换为单个或多个接口。这到底是什么意思?举个例子会有很大帮助。
通常访问单例,例如SingletonInstance si = SingletonInstance.getInstance()
。有两个步骤可以从 TDD 中迁移出来。
首先是不直接使用SingletonInstance
,而是像作者所说的"a single or multiple interfaces",比如SingletonService ss = SingletonInstance.getInstance()
这样的服务API SingletonService
是实例实现的接口。对于 "multiple" 的情况,单例 API 可能会被分解成接口,每个接口都有更小但内聚的范围,因此每个接口都遵守 single responsibility principle.
第二步,特别是对于 TDD,是注入实例而不是查找实例。如果你的模块知道如何找到它需要的东西,那么它耦合太多而不能简单地模拟。但是,如果您的模块提供了它需要的服务(通过构造函数、修改器、DI 等),那么您的模拟框架可以使用实现 API 足以执行测试的模拟服务轻松测试您的模块。
我看到一篇关于 TDD 的文章,其中作者提到 Singleton 是一种反模式,为了避免这种情况,一个解决方案是应该将 Singleton 替换为单个或多个接口。这到底是什么意思?举个例子会有很大帮助。
通常访问单例,例如SingletonInstance si = SingletonInstance.getInstance()
。有两个步骤可以从 TDD 中迁移出来。
首先是不直接使用SingletonInstance
,而是像作者所说的"a single or multiple interfaces",比如SingletonService ss = SingletonInstance.getInstance()
这样的服务API SingletonService
是实例实现的接口。对于 "multiple" 的情况,单例 API 可能会被分解成接口,每个接口都有更小但内聚的范围,因此每个接口都遵守 single responsibility principle.
第二步,特别是对于 TDD,是注入实例而不是查找实例。如果你的模块知道如何找到它需要的东西,那么它耦合太多而不能简单地模拟。但是,如果您的模块提供了它需要的服务(通过构造函数、修改器、DI 等),那么您的模拟框架可以使用实现 API 足以执行测试的模拟服务轻松测试您的模块。