public class Connection : IConnection
{
public Connection(Uri baseAddress, ISerializer serializer)
{
BaseAddress = baseAddress;
Serializer = serializer;
ResponseFactory = new ResponseFactory(serializer);
}
private Uri BaseAddress { get; set; }
public IResponseFactory ResponseFactory { get; set; }
private ISerializer Serializer { get; }
}在这段代码中(为简洁而编辑),Connection类有两个依赖项,它们通过构造函数注入获得。
它有第三个依赖项,在IResponseFactory上,属性注入是可用的,但是缺省值是通过构造函数中的行ResponseFactory = new ResponseFactory(serializer)创建的。我认为ResponseFactory是一个合适的‘本地默认’,使用Mark的术语,但是Connection类的用户可以自由地提供一个他们想要的替代IResponseFactory。
在一段时间后重新查看此代码时,对于构造函数中本地默认值的创建及其对ISerializer的依赖,我感到矛盾。虽然ISerializer是Connection类所要求的,但将它与ResponseFactory“链接”在一起似乎是错误的。感觉上Connection类应该通过构造函数需要一个IResponseFactory,而放弃了本地默认值的方便性及其对ISerializer的依赖,而这种依赖恰好也被注入到该类中。
你认为如何?这是定义的“气味”吗?
发布于 2018-04-04 10:56:01
是的,这看上去确实有点奇怪,原因有很多。
标准“代码嗅觉”免责声明
发布于 2018-05-04 16:33:40
问题是,ResponseFactory是否有必要做任何有意义的事情。
是?然后,应该通过构造函数注入来提供。一方面,构造函数提供了某种合理的缺省值,这是很好的。但另一方面,构造函数注入使事情变得明确。
没有吗?那么就不需要一个locale default了。一个简单的未初始化字段就足够了--代价是null检查。当它是不需要的,万一它是,但它被忽视了,应该有一个明确的信号(除了NPE),来电者没有做他的家庭作业。
关于@Ewan的答复:
属性和构造函数注入的混合
我认为通过构造函数注入提供必要的依赖没有问题,而通过setter注入提供可选的依赖没有问题。
https://softwareengineering.stackexchange.com/questions/368810
复制相似问题