簡體   English   中英

為.NET Framework接口實現接口隔離原理

[英]Implement Interface Segregation Principle for .NET Framework interfaces

我在自定義ServiceLocator類中實現了IServiceLocator(CommonServiceLocator包)。

該接口具有以下實現方法:

public class CustomServiceLocator : IServiceLocator
{
    private IServiceProvider _provider;

    public RatioDissectionServiceLocator(IServiceProvider provider)
    {
        _provider = provider;
    }

    public IEnumerable<object> GetAllInstances(Type serviceType)
    {
        throw new NotImplementedException();
    }

    public IEnumerable<TService> GetAllInstances<TService>()
    {
        throw new NotImplementedException();
    }

    public object GetInstance(Type serviceType)
    {
        throw new NotImplementedException();
    }

    public object GetInstance(Type serviceType, string key)
    {
        throw new NotImplementedException();
    }

    public TService GetInstance<TService>()
    {
        return _provider.GetService<TService>();
    }
 }

我不想在課堂上實現所有方法。 我們如何為內置的C#接口實現ISP?

有什么幫助嗎?

接口隔離原理指出:

不應強迫任何客戶端依賴其不使用的方法。

這意味着盡管對原理有許多不清楚和誤導性的解釋,但大型界面本身並沒有違反該原理。 也許另一個類實際上確實依賴於接口的所有成員。 因此,我們不會查看類似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();
    }
}

現在,需要依賴於一種方法的類可以僅依賴於具有該一種方法的接口。 (隨着時間的流逝,我發現這會導致很多單方法接口。我認為從邏輯上講, 這取決於函數和委托,但是單方法接口是可以的。

那就是接口隔離。 您的課程不依賴於不需要的大型接口。 它們取決於一個或多個准確描述其需求的接口。 這通常是通過從需要依賴它的類的角度創建接口來實現的。


您可能會發現,沒有類需要依賴於IServiceLocator所有方法。

也許您只需要這樣:

TService GetInstance<TService>();

但是,類真的需要依賴可以返回任何內容的方法嗎? 換句話說,您可能只會請求一個或兩個依賴項。 因此,也許您真正需要的是:

public interface ISomethingSpecificFactory
{
    ISomethingSpecific CreateInstance();
}

或者,您可能會發現根本不需要工廠-也許您可以只注入ISomethingSpecific而不是創建ISomethingSpecific實例的工廠。

另一種查看方式:如果不需要實現IServiceLocator所有方法,則無需創建實現IServiceLocator的類。


IServiceLocator框架接口。 與我們創建的大多數軟件不同,它並不滿足狹窄的特定需求。 它滿足了我們編寫軟件時確定的各種需求。 這就是為什么它具有我們可能不需要的各種方法的意義。

ISP的一個原因是,如果許多類依賴於接口的不同成員,則由於一個客戶端的需求,我們可能會被迫更改接口,而這些更改會影響依賴於其他方法的其他客戶端,實際上是耦合他們在一起。

我們無法更改IServiceLocator以使壓力不存在。 因此,從技術上講,即使我們確實依靠該接口違反了ISP,也不會產生ISP保護我們免受損害的有害影響。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM