继承和接口隔离原则

时间:2013-07-10 07:32:28

标签: c# inheritance solid-principles interface-segregation-principle

具有未使用方法的类的继承是否违反了接口隔离原则?

例如:

abstract class Base
{
    public void Receive(int n)
    {
        // . . . (some important work)

        OnMsg(n.ToString());
    }

    protected abstract void OnMsg(string msg);
}

class Concrete : Base
{
    protected override void OnMsg(string msg)
    {
        Console.WriteLine("Msg: " + msg);
    }
}

Concrete取决于方法Base.Receive(int n),但它从不使用它。

UPD

我使用的定义:

  

ISP声明不应该强迫任何客户端依赖它的方法   不使用。

2 个答案:

答案 0 :(得分:7)

我认为你误解了界面隔离原则所说的内容。在你的情况下你很好,并没有“强迫”任何实施。事实上,您正在应用Template method design pattern

如果你有一个假设的

interface ICommunicateInt
{
  int Receive();
  void Send(int n);
}

为了实现它,您的Base类将被迫实现它不需要的Send方法。 因此,ISP建议最好:

interface ISendInt
{
  void Send(int n);
}

interface IReceiveInt
{
  int Receive();
}

所以你的课程可以选择实施一个或两个。此外,其他类中需要可以发送Int的类的方法也需要

void Test(ISendInt snd)
// void Test(ICommunicateInt snd) // Test would "force" snd to depend on 
                                  // a method that it does not use 

答案 1 :(得分:0)

我没有看到具体“依赖”Base.Receive()在我使用该术语的方式。如果接收被修改,混凝土将如何改变?我会争辩,根本不是。假设我们用不同名称或不同签名的方法替换Receive(),Concrete将不知道。具体调用Receive()吗?不,所以我认为这里没有依赖于Receive()。

依赖是使用签名OnMsg(),Concrete参与与Base的非常特殊的关系,履行OnMsg()契约。

但是在不同的意义上,Concrete非常依赖于Base.Receive(),它是外部世界的接口 - 如果没有这种方法,没有人可以访问Concrete的功能。在这个意义上,混凝土“使用”Base.Receive()在一个非常基础的层面。