Я хотел бы сослаться на пример, который использовался ранее на SO с уткой и электрической уткой:
public interface IDuck
{
void Swim();
}
public class Duck : IDuck
{
public void Swim()
{
//do something to swim
}
}
public class ElectricDuck : IDuck
{
public void Swim()
{
if (!IsTurnedOn)
return;
//swim logic
}
public void TurnOn()
{
this.IsTurnedOn = true;
}
public bool IsTurnedOn { get; set; }
}
Первоначальное нарушение LSP могло бы выглядеть так:
void MakeDuckSwim(IDuck duck)
{
if (duck is ElectricDuck)
((ElectricDuck)duck).TurnOn();
duck.Swim();
}
Одно из решений автора заключалось в том, чтобы поместить логику в метод плавания электрической утки, чтобы она включалась:
public class ElectricDuck : IDuck
{
public void Swim()
{
if (!IsTurnedOn)
TurnOn();
//swim logic
}
public void TurnOn()
{
this.IsTurnedOn = true;
}
public bool IsTurnedOn { get; set; }
}
Я пришел в других сценариях, где может быть создан расширенный интерфейс, поддерживающий какую-либо инициализацию:
public interface IInitializeRequired
{
public void Init();
}
Electric Duck затем может быть расширен с помощью этого интерфейса:
public class ElectricDuck : IDuck, IInitializeRequired
{
public void Swim()
{
if (!IsTurnedOn)
return;
//swim logic
}
public void TurnOn()
{
this.IsTurnedOn = true;
}
public bool IsTurnedOn { get; set; }
#region IInitializeRequired Members
public void Init()
{
TurnOn();
}
#endregion
}
РЕДАКТИРОВАТЬ: Причина расширенного интерфейса основана на утверждении автора, что включение автоматически в методе плавания могут иметь другие нежелательные результаты.
Тогда метод вместо проверки и преобразования к определенному типу может вместо этого искать расширенный интерфейс:
void MakeDuckSwim2(IDuck duck)
{
var init = duck as IInitializeRequired;
if (init != null)
{
init.Init();
}
duck.Swim();
}
Тот факт, что я сделал концепцию инициализации более абстрактной, чем для создания расширенного интерфейса под названием IElectricDuck с методом TurnOn (), Может показаться, что я поступил правильно, однако вся концепция Init может существовать только из-за электрического утка.
Это лучший способ / решение или это просто замаскированное нарушение LSP.
Спасибо