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

时间:2013-07-19 16:10:57

标签: c# oop design-patterns solid-principles interface-segregation-principle

提醒(来自wiki):

  

接口隔离原则(ISP)声明没有客户端应该   被迫依赖它不使用的方法。

现在看看我的例子。

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

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

2 个答案:

答案 0 :(得分:2)

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

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

  
      
  1. ISP是关于真实物体的。您不得对传入参数使用“过多”引用。
  2.   

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

  
      
  1. ISP是关于课程的。如果您的类已在某处使用完整接口,则无需在特定方法中限制引用类型。在这个例子中,ICounter接口过多。
  2.   

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

  
      
  1. 从SOLID原则来看,这种架构是完全错误的(那么为什么?)。
  2.   

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

答案 1 :(得分:0)

我认为将IncrementAndSend方法添加到接口并使类OneToManyRouter依赖于IEnumerable&lt; ICounter&gt;会更好。 在我看来,这不是ISP违规,因为NewNumber事件操作和IncrementAndSend方法是严格相关的。 希望它可以帮到你。