首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >将方法绑定到实现类

将方法绑定到实现类
EN

Stack Overflow用户
提问于 2010-09-03 23:45:55
回答 7查看 694关注 0票数 11

这是否给代码带来了异味或违反了SOLID原则?

代码语言:javascript
运行
复制
public string Summarize()
{
IList<IDisplayable> displayableItems = getAllDisplayableItems();
StringBuilder summary = new StringBuilder();

foreach(IDisplayable item in displayableItems)
{
    if(item is Human)
        summary.Append("The person is " + item.GetInfo());

    else if(item is Animal) 
        summary.Append("The animal is " + item.GetInfo());

    else if(item is Building) 
        summary.Append("The building is " + item.GetInfo());

    else if(item is Machine) 
        summary.Append("The machine is " + item.GetInfo());
}

return summary.ToString();
}

正如您所看到的,我的Summarize()绑定到实现类,如Human、Animal等。

此代码是否违反了LSP?(还有其他可靠的原则吗?)

EN

回答 7

Stack Overflow用户

回答已采纳

发布于 2010-09-04 00:10:22

考虑到OP对this answer的评论,我认为最好的方法是创建一个自定义容器类来替换具有containsHumans()containsAnimals()等方法的IList<IDisplayable> displayableItems,这样您就可以将讨厌的非多态代码封装在一个地方,并保持Summarize()函数中的逻辑清晰。

代码语言:javascript
运行
复制
class MyCollection : List<IDisplayable>
{
    public bool containsHumans()
    {
        foreach (IDisplayable item in this)
        {
            if (item is Human)
                return true;
        }

        return false;
    }

    // likewise for containsAnimals(), etc
}

public string Summarize()
{
    MyCollection displayableItems = getAllDisplayableItems();
    StringBuilder summary = new StringBuilder();

    if (displayableItems.containsHumans() && !displayableItems.containsAnimals())
    {
        // do human-only logic here
    }
    else if (!displayableItems.containsHumans() && displayableItems.containsAnimals())
    {
        // do animal-only logic here
    }
    else
    {
        // do logic for both here
    }

    return summary.ToString();
}

当然,我的例子过于简单和做作。例如,无论是作为Summarize() if/else语句中逻辑的一部分,还是围绕整个代码块,您都需要遍历displayableItems集合。此外,如果在MyCollection中覆盖Add()Remove(),并让它们检查对象的类型并设置标志,那么您可能会获得更好的性能,这样您的containsHumans()函数(和其他函数)就可以简单地返回标志的状态,而不必在每次调用它们时迭代集合。

票数 1
EN

Stack Overflow用户

发布于 2010-09-03 23:48:32

我闻到了一点东西..。

如果您的类都实现了IDisplayable,那么它们都应该实现自己的逻辑来显示自己。这样你的循环就会变得更干净:

代码语言:javascript
运行
复制
public interface IDisplayable
{
    void Display();
    string GetInfo();
}

public class Human : IDisplayable
{
    public void Display() { return String.Format("The person is {0}", 
        GetInfo());

    // Rest of Implementation
}

public class Animal : IDisplayable
{
    public void Display() { return String.Format("The animal is {0}", 
        GetInfo());

    // Rest of Implementation
}

public class Building : IDisplayable
{
    public void Display() { return String.Format("The building is {0}", 
        GetInfo());

    // Rest of Implementation
}

public class Machine : IDisplayable
{
    public void Display() { return String.Format("The machine is {0}", 
        GetInfo());

    // Rest of Implementation
}

然后,您可以将您的循环更改为更清晰的东西(并允许类实现自己的显示逻辑):

代码语言:javascript
运行
复制
foreach(IDisplayable item in displayableItems)
    summary.Append(item.Display());
票数 21
EN

Stack Overflow用户

发布于 2010-09-03 23:50:01

看起来IDisplayable应该有一个用于显示名称的方法,所以您可以将该方法简化为如下所示

代码语言:javascript
运行
复制
summary.Append("The " + item.displayName() + " is " + item.getInfo());
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/3637377

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档