繁体   English   中英

阶级使用陷阱打破Liskov替代原则

[英]Class usage pitfalls breaking Liskov Substitution Principle

在我最近工作的一个项目中,注意到一些接受属于层次结构的类的方法具有类似于以下的代码:

public void Process(Animal animal) {
    if(animal.GetType() == typeof(Dog)) {
        Console.WriteLine("We have a dog");
    }
    else {
        Console.WriteLine("not a dog");
    }
}

好吧,这让我感到公然违反了LSP ,因为现在如果你使用狗的子类 ,无论是在生产代码,单元测试模拟,还是作为依赖注入拦截器的一部分, 这个代码将不会以相同的方式工作 我相信通过将条件更改为:可以轻松修复此特定方案:

  if (animal is Dog)

这让我想到了:

是否有任何其他缺陷可以破坏客户端代码中的LSP?

UPDATE

只是为了澄清,我正在寻找在层次结构中使用类的代码中可能存在的缺陷。 我知道,我不是在寻找层次结构严重的问题 - (例如矩形 - 方形问题)。 我试图找出要查找的内容,以确保代码将支持动态模拟,拦截器,装饰类(例如LoggingDog),就像处理原始类一样。

通过答案和链接后到目前为止,我可以看到唯一的缺陷是直接使用类的类型 - 直接使用GetType()方法或通过其他技术。 尽管这里的一些意见isas运营商,甚至铸造基地型在这种情况下,不会破坏LSP作为子类将评估以同样的方式原班会。

如果我们暂时忽略了您确实需要转换为特定类型的情况,在大多数情况下,可以通过更改设计来解决问题:

public class Animal
{
    public virtual void Process()
    {
        Console.WriteLine("Animal (not a dog)");
    }
}

public class Dog : Animal
{
    public override void Process()
    {
        Console.WriteLine("We have a dog");
    }
}

通过使用这种设计,我们避免了在处理动物的代码中施放:

var animal = ...; // maybe a Dog, maybe not
animal.Process();

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM