Прямо сейчас у меня есть своего рода дилемма. Существует класс структура, которая подобна следующему:Разделительные интерфейсы и впрыск конструктора
public interface IMammal
{
void Eat();
}
public interface IBarking
{
void Bark();
}
Есть случаи IBarking
и IMammal
. Теоретически наше животное может быть любым из них или только одним. Cow
- это, как вы можете видеть, IMammal
, и Dog
- IMammal
и IBarking
. В теории у нас может быть даже кто-то, кто может лаять, но не является млекопитающим.
public class Mammal : IMammal
{
public void Eat()
{
Console.Write("Om-nom-nom");
}
}
public class Cow : Mammal
{
}
public class Dog : Mammal, IBarking
{
public void Bark()
{
Console.Write("Bark-bark!!!");
}
}
Вот Farm
, где только одно животное живет:
public class Farm
{
private readonly IMammal _animal;
public Farm(IMammal animal)
{
_animal = animal;
}
public void Feed()
{
_animal.Eat();
}
public void Guard()
{
var dog = _animal as IBarking;
if (dog != null)
dog.Bark();
}
}
Проблема, я вижу здесь, является то, что мы предполагаем, что IBarking
всегда IMammal
. Что не так с этим дизайном, как оно может быть исправлено?
Вы предполагаете, что 'Собака' всегда' IMammal', какой она есть, хотя 'IMammal' не может быть' Dog'. Я не уверен, где вы видите, что «Ибаркинг» считается «IMammal» в коде? Вы выбираете конкретный тип, вы могли бы сделать что-то вроде «var barker = _animal as IBarking», что сделало бы ваш вопрос понятным ... Но даже это не предполагает, что «Ибаркинг» является млекопитающим, только то, что млекопитающее * может * реализовать его. –
@RonBeyer Извините. Это моя ошибка. Я скорректировал код, чтобы теперь я перешел на «ИБаркинг». Ситуация в том, что я не могу предоставить какой-либо другой «ИБаркинг», кроме тех, кто реализует «IMammal». – dmigo
Ваша реализация, кстати, написанная, может принимать только «IMammals», а Guard будет делать только «ИБаркинг», поэтому по дизайну он может принимать только лающих млекопитающих, если «Страж» должен что-либо сделать. Если вы хотите, чтобы он принимал все «Ибаркинг», независимо от того, были ли они млекопитающими, вам нужно использовать «ИБаркинг» в конструкторе и выполнить ту же проверку в «Корректировке». Возможно, вам нужно создать более высокий интерфейс, например, «IAlive» или «IFauna», которые могут инкапсулировать как млекопитающих, так и лаять «вещи» (при условии, что все лаки живы). –