当前位置:  开发笔记 > 编程语言 > 正文

避免LSP违规的最佳方法

如何解决《避免LSP违规的最佳方法》经验,为你挑选了1个好方法。

让我们考虑以下示例.我有这样的类的层次结构:

abstract class Base
{
    public abstract void DoSomething();
}

class Foo : Base
{
    public override void DoSomething()
    {
        Console.WriteLine("Foo. DoSomething...");
    }
}

class Bar : Base
{
    public override void DoSomething()
    {
        Console.WriteLine("Bar. DoSomething...");

        if (ShouldDoSomethingElse)
        {
            DoSomethingElse();
        }
    }

    public void DoSomethingElse()
    {
        Console.WriteLine("Bar. DoSomething else...");
    }

    public bool ShouldDoSomethingElse { get; set; }
}

我的客户端是这样的:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();
        var bar = new Bar();
        var items = new List {foo, bar};

        HandleItems(items);
    }

    static void HandleItems(IEnumerable items)
    {
        foreach (var item in items)
        {
            if (item is Bar)
            {
                //Code smell! LSP violation.
                var bar = item as Bar;
                bar.ShouldDoSomethingElse = true;
            }
            item.DoSomething();
        }
    }
}

请注意,我们可以有几个客户端,其中一些可能需要ShouldDoSomethingElse ='true'其他'false'.

当然,在HandleItems()中以不同方式处理项目是设计错误和Liskov替换原则违规的标志.

你会建议什么方法或模式摆脱这种代码气味?

如果已经提出过类似的问题,我很抱歉.



1> Steven..:

您的代码不违反Liskov替换原则.该原则仅表明所有子类型必须以兼容的方式运行,而不会在注入不同的实现时破坏消费者.在你的例子中.当您提供不同类型时,代码不会中断.

然而,向下转换Bar是一种代码气味,因为HandleItems违反了依赖性倒置原则,因为HandleItems现在依赖于具体类型而不是抽象.此外,此代码可能导致稍后打开/关闭原则违规,因为HandleItems每次Base添加新子类型时可能需要更改方法.一旦您需要更改HandleItems它意味着它不会被关闭进行修改.

然而,你的例子是抽象的,这使得很难给出一些精确的反馈,但总的来说,我会说你应该将设置的责任ShouldDoSomethingElse转移给调用者,例如:

var foo = new Foo();
var bar = new Bar { ShouldDoSomethingElse = true };
var items = new List { foo, bar };

HandleItems(items);

这可以防止HandleItems必须知道有关派生类型的任何信息(允许派生类型单独部署)并防止HandleItems不断变化.

推荐阅读
mobiledu2402851323
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有