【发布时间】:2015-11-03 21:51:03
【问题描述】:
现在我有一种困境。有一个类结构类似于以下:
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。这个设计有什么问题,怎么解决?
【问题讨论】:
-
您假设
Dog始终是IMammal,尽管IMammal可能不是Dog。我不确定您在哪里看到IBarking在代码中被假定为IMammal?你正在选择一个具体的类型,你可以做像var barker = _animal as IBarking这样的事情,这会让你的问题有意义......但即使这样也不能假设IBarking是哺乳动物,只是哺乳动物可能 i> 实施它。 -
@RonBeyer 对不起。这是我的错。我已经更正了代码,现在我将其转换为
IBarking。情况是我不能提供任何其他类型的IBarking,除了那些实现IMammal的人。 -
你的实现,顺便说一句,只能接受
IMammals,而Guard只会做IBarking,所以如果Guard做任何事情,它只能接受吠叫的哺乳动物。如果您希望它接受所有IBarking,无论它们是哺乳动物,那么您需要在构造函数中使用IBarking,并在Feed中执行相同的检查。也许你需要做一个更高级的接口,比如IAlive或IFauna,可以封装哺乳动物和吠叫的“东西”(假设吠叫的东西是活的)。
标签: c# oop dependency-injection architecture