c# – 关于类或对象的接口隔离原则是什么?

提醒(从
wiki):

The interface-segregation principle (ISP) states that no client should
be forced to depend on methods it does not use.

现在看看我的例子.

这是我可变的实体.它是从某个地方编辑的,它能够通过只读接口通知有关更改:

interface ICounter
{
    event Action<int> NewNumber;
}

class Counter : ICounter
{
    public event Action<int> NewNumber;

    int number = 0;
    public void IncrementAndSend(int x)
    {
        number += x;
        if (NewNumber != null) NewNumber(number);
    }
}

这是使用它的传输层的类.看看两种注射变体(Attach_1和Attach_2)以及我的假设如下:

class OneToManyRouter
{
    IEnumerable<Counter> _destinations;

    public OneToManyRouter(IEnumerable<Counter> destinations)
    {
        _destinations = destinations;
    }

    // 1         
    public void Attach_1(ICounter source)
    {
        source.NewNumber += (n) =>
        {
            foreach (var dest in _destinations) dest.IncrementAndSend(n);
        };
    }

    // 2 
    public void Attach_2(Counter source)
    {
        source.NewNumber += (n) =>
        {
            foreach (var dest in _destinations) dest.IncrementAndSend(n);
        };
    }
}

> ISP是关于真实物体的.你不能使用“过度”
对传入参数的引用.
> ISP是关于课程的.如果您的班级已使用完整界面
某处,不需要在特定方法中限制引用类型.
在这个例子中,ICounter接口过多.
>从SOLID的角度来看,这种架构是完全错误的
原则(那么为什么?).

最佳答案 ISP既不是类,也不是对象,而是严格关于接口,特别是关于接口设计.该原则旨在阻止在单个接口中对半相关方法进行分组,以避免用户只需要这些方法的子集将其余部分实现为空函数(抛出NotImplementedException或将其保留为字空:{}) .因此,更容易实现更一致的类并更有效地使用接口.

在您的示例中,您将Counter类与ICounter接口组合在一起,其方式与ISP概念没有直接关系:

  1. ISP is about real objects. You must not use “excessive” references to incoming parameters.

这部分是正确的(如果我正确地解释“过度”的概念).但是,正如我所提到的,ISP并不是关于如何与真实对象进行交互,而是如何定义有用的界面.

  1. ISP is about classes. If your class already uses full interface somewhere, no need to restrict reference type in particular methods. ICounter interface is excessive in this example.

这是不正确的.如果您在具体类而不是在接口上创建依赖项,则该类实现接口的事实并不意味着什么.请记住,通过使组件依赖于合同而不是将来可能会更改的特定实现,接口提供了程序各个部分的分离.通过使用具体课程,您将失去这种好处.而且,这与ISP概念并不完全相关.

  1. This architecture is completely wrong from the point of SOLID principles (then why?).

从体系结构的角度强调SOLID原则,我建议依赖于ICounter而不是Counter,并将IncrementAndSend作为接口定义的一部分.

点赞