【发布时间】:2018-02-06 17:03:44
【问题描述】:
我开始应用 SOLID 原则,但发现它们有些矛盾。我的问题如下:
我对依赖倒置原则的理解是类应该依赖于抽象。在实践中,这意味着类应该从接口派生。到目前为止一切都很好。
接下来我对开闭原则的理解是,在某个截止点之后,你不应该改变一个类的内容,而应该扩展和覆盖。到目前为止,这对我来说很有意义。
因此,鉴于上述情况,我最终会得到这样的结果:
public interface IAbstraction
{
string method1(int example);
}
public Class Abstraction : IAbstraction
{
public virtual string method1(int example)
{
return example.toString();
}
}
然后在时间 T,method1 现在需要在其返回值上添加“ExtraInfo”。我不会更改当前的实现,而是创建一个扩展 Abstraction 的新类,并让它做我需要的事情,如下所示。
public Class AbstractionV2 : Abstraction
{
public override string method1(int example)
{
return example.toString() + " ExtraInfo";
}
}
而且我可以看到这样做的原因是只有我想调用这个更新方法的代码会调用它,其余的代码会调用旧方法。
一切对我来说都有意义 - 我认为我的理解是正确的??
不过,我也在使用依赖注入(简单注入器),所以我的实现从来不是通过具体的类,而是通过我的 DI 配置,如下:
container.Register<IAbstraction, Abstraction>();
这里的问题是,在此设置下,我可以将我的 DI 配置更新为:
container.Register<IAbstraction, AbstractionV2>();
在这种情况下,所有实例现在都将调用新方法,这意味着我未能实现不更改原始方法。
或
我创建了一个新接口 IAbstractionV2 并在那里实现了更新的功能 - 意味着接口声明的重复。
我看不到任何解决方法 - 这让我想知道依赖注入和 SOLID 是否兼容?还是我在这里遗漏了什么?
【问题讨论】:
-
"意思是我没能做到不改变原来的方法。"我不确定是不是这样。原始方法作为未修改的
Abstraction类坐在那里。 -
也就是说,如果您的问题只是想更改用于有限数量消费者的实现,您可以为您的
AbstractionV2类添加一个IAbstractionV2 : IAbstraction接口来实现,然后注入@987654330 @通过那个。 -
您是否曾经在全球范围内使用过
IAbstraction的一种实现?看起来没有任何东西直接依赖于Abstraction.method1,所以您可以简单地删除它? -
请注意,OCP 并不禁止更改现有代码,但其想法是防止彻底更改。所以一旦你看到一个变化导致许多类发生变化,那就表明违反了 OCP。
标签: c# solid-principles