为.NET Framework接口实现接口隔离原理

时间:2019-04-04 12:42:21

标签: c# .net

我正在将IServiceLocator(CommonServiceLocator包)实现到我的自定义ServiceLocator类中。

该接口具有以下实现方法:

<svg viewBox="-304 -506 608 1005" >
    <g id="theg">
      <image id="1554312687213" xlink:href="https://lobservateur-avesnois.easypubphr.fr/wp-content/uploads/sites/6/2018/11/restaurantmodel.png" x="-733" y="-750" width="1461" height="1564"></image>
</g>
    <g id="theText" text-anchor="middle" fill="#ffffff">
        <text font-family="ABeeZee" font-size="43" font-style="normal" font-weight="bold" >Votre entreprise</text>
      <text font-family="ABeeZee" y="30" font-size="20" >Votre adresse</text>
      <text font-family="ABeeZee" font-size="18" y="60" >Votre telephone</text>
    </g>
</svg>

我不想在类中实现所有方法。如何为内置的C#接口实现ISP?

有帮助吗?

1 个答案:

答案 0 :(得分:4)

接口隔离原则指出:

  

任何客户端都不应被迫依赖不使用的方法。

这意味着,尽管对该原则有许多不清楚和误导性的解释,但是一个大的接口本身并没有违反该原则。也许另一个类实际上确实依赖于接口的所有成员。因此,我们不会查看类似IServiceLocator的界面,而是尝试以某种方式“修复”它。

从依赖于接口的类的角度来看,ISP是如果一个接口有20个成员,而我的班级都依赖于这些成员,则这不是ISP违规。 (很可能还有其他与ISP无关的其他坏事情。)如果另一个类依赖于完全相同的接口,并且仅使用几个成员,则这是ISP违规的。

在两个示例中,它都是相同的界面。原理与界面无关。这取决于依赖于接口的类是否使用了其所有成员。

(我看到的另一个奇怪的例子是一个大接口和一个类,该类实现了该接口,但对某些成员抛出了NotImplementedException。这也很糟糕,它违反了Liskov换人规则,但与ISP完全无关。实现接口与无关

一种避免违反ISP的方法是从依赖于它们的类的角度编写接口。无论您的类需要从其依赖项中获取什么,都可以编写接口来对其进行准确描述。如果具体的内部实现是具有100个成员的框架类,则将其包装在您自己的类中:

public interface ISmallSegregatedInterface
{
    void DoJustWhatMyClassNeeds();
}

public class TheImplementation : ISmallSegregatedInterface
{
    private readonly FrameworkClassWithLotsOfMembers _inner;

    public TheImplementation(FrameworkClassWithLotsOfMembers inner)
    {
        _inner = inner;
    }

    public void DoJustWhatMyClassNeeds()
    {
        _inner.CallSomeMethod();
    }
}

现在,需要依赖于一种方法的类可以仅依赖于具有该一种方法的接口。 (随着时间的流逝,我发现这会导致很多单方法接口。我认为从逻辑上讲会导致depending on functions and delegates,但是单方法接口是可以的。

这是接口隔离。您的课程不依赖于不需要的大型接口。它们取决于一个或多个准确描述其需求的接口。这通常是通过从需要依赖它的类的角度创建接口来实现的。


您可能会发现,没有类需要依赖于IServiceLocator的所有方法。

也许您只需要这样:

TService GetInstance<TService>();

但是,类是否真的需要依赖于可以返回任何东西的方法?换句话说,您可能只会请求一个或两个依赖项。所以也许您真正需要的是这个:

public interface ISomethingSpecificFactory
{
    ISomethingSpecific CreateInstance();
}

或者您可能会发现根本不需要工厂-也许您可以只注入ISomethingSpecific而不是创建 ISomethingSpecific 实例的工厂。

另一种查看方法:如果不需要实现IServiceLocator的所有方法,则无需创建实现IServiceLocator的类。


IServiceLocator是一个框架界面。与我们创建的大多数软件不同,它并不满足狭窄的特定需求。它满足了我们编写软件时确定的各种需求。这就是为什么它具有我们可能不需要的各种方法的意义。

ISP的一个原因是,如果许多类依赖于接口的不同成员,则可能由于一个客户端的需求而不得不更改接口,而这些更改会影响依赖于其他方法的其他客户端,实际上将它们耦合在一起。

我们不能更改IServiceLocator,以便不存在压力。因此,从技术上讲,即使我们 did 依靠该接口违反了ISP,也不会产生ISP保护我们免受损害的有害影响。