ServiceLocator是反模式吗?最近我读过Mark Seemann关于Service Locator反模式的文章。作者指出ServiceLocator为反模式的两个主要原因:API使用问题(我完全可以使用)当类使用服务定位器时,很难看到它的依赖关系,因为在大多数情况下,类只有一个PARAMETERLESS构造函数。与ServiceLocator相比,DI方法通过构造函数的参数显式地暴露依赖关系,因此在IntelliSense中很容易看到依赖关系。维护问题(让我感到困惑)请考虑以下示例我们有一个使用服务定位器方法的类'MyType':public class MyType{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
}}现在我们要为类'MyType'添加另一个依赖项public class MyType{
public void MyMethod()
{
var dep1 = Locator.Resolve<IDep1>();
dep1.DoSomething();
// new dependency
var dep2 = Locator.Resolve<IDep2>();
dep2.DoSomething();
}}这就是我的误解开始的地方。作者说:要判断你是否引入了一个重大改变,要变得更加困难。您需要了解使用Service Locator的整个应用程序,编译器不会帮助您。但是等一下,如果我们使用DI方法,我们将在构造函数中引入与另一个参数的依赖关系(在构造函数注入的情况下)。问题仍然存在。如果我们忘记设置ServiceLocator,那么我们可能忘记在IoC容器中添加新的映射,并且DI方法将具有相同的运行时问题。此外,作者还提到了单元测试的难点。但是,我们不会有DI方法的问题吗?我们不需要更新所有实例化该类的测试吗?我们将更新它们以传递一个新的模拟依赖项,以使我们的测试可编译。我没有看到更新和时间花费带来任何好处。我不是想捍卫Service Locator方法。但这种误解让我觉得我失去了一些非常重要的东西。有人可以消除我的怀疑吗?更新(摘要):我的问题“服务定位器是反模式”的答案实际上取决于具体情况。我绝对不会建议你从工具列表中删除它。当您开始处理遗留代码时,它可能会变得非常方便。如果你很幸运能够处于项目的最初阶段,那么DI方法可能是更好的选择,因为它比Service Locator有一些优势。以下是主要的不同之处,这些差异使我不相信我的新项目使用Service Locator:最明显和最重要的是:Service Locator隐藏了类依赖项如果您正在使用某个IoC容器,它可能会在启动时扫描所有构造函数以验证所有依赖项,并为您提供有关丢失映射(或错误配置)的即时反馈; 如果您将IoC容器用作服务定位器,则无法实现此目的有关详细信息,请阅读下面给出的优秀答案。
3 回答
潇湘沐
TA贡献1816条经验 获得超6个赞
我还想指出,如果你重构遗留代码,服务定位器模式不仅不是反模式,而且它也是一种实际需要。没有人会在数百万行代码上挥动魔杖,突然所有的代码都准备就绪了。因此,如果您想开始将DI引入现有代码库,通常情况下您会将内容更改为DI服务,并且引用这些服务的代码通常不会是DI服务。因此,这些服务将需要使用服务定位器,以获取已转换为使用DI的那些服务的实例。
因此,当重构大型遗留应用程序以开始使用DI概念时,我会说服务定位器不仅不是反模式,而且它是将DI概念逐渐应用于代码库的唯一方法。
- 3 回答
- 0 关注
- 819 浏览
添加回答
举报
0/150
提交
取消