Наследование и принцип разделения интерфейса
Влияет ли наследование от класса с неиспользуемыми методами на принцип разделения интерфейса?
Например:
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
Определение я использую:
Провайдер заявляет, что ни один клиент не должен зависеть от методов, которые он не использует.
2 ответа
Я думаю, что вы неправильно истолковываете принцип разделения интерфейса. В вашем случае вы в порядке и не "форсируете" какую-либо реализацию. На самом деле вы применяете шаблон дизайна метода Template
Если у вас была гипотетическая
interface ICommunicateInt
{
int Receive();
void Send(int n);
}
чтобы реализовать это, ваш Base
класс будет вынужден реализовать Send
метод, который ему не нужен. Итак, интернет-провайдер предполагает, что лучше иметь:
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
Я не вижу, что Concrete "зависит" от Base.Receive () так, как я бы использовал этот термин. Как Бетон нужно будет изменить, если получит изменение? Я бы поспорил, совсем нет. Предположим, что мы заменили Receive () на метод с другим именем или с другой подписью, Concrete не будет знать. Бетон вызывает функцию Receive ()? Нет. Поэтому я не вижу здесь никакой зависимости от Receive ().
Зависимость с сигнатурой OnMsg (), Concrete участвует в очень определенных отношениях с Base, выполняя этот контракт OnMsg ().
Но в другом смысле Concrete очень сильно зависит от Base.Receive (), который является его интерфейсом с внешним миром - без этого метода никто не сможет получить доступ к возможностям Concrete. В этом смысле Бетон "использует" Base.Receive() на очень фундаментальном уровне.