这个坏习惯/反模式的名称是什么?

44
我正在尝试向我的团队解释为什么这是不良实践,并寻找反模式参考来帮助我进行解释。这是一个非常大的企业应用程序,因此这里有一个简单的示例来说明所实现的内容:
public void ControlStuff()
    {
        var listOfThings = LoadThings();
        var listOfThingsThatSupportX = new string[] {"ThingA","ThingB", "ThingC"};
        foreach (var thing in listOfThings)
        {
            if(listOfThingsThatSupportX.Contains(thing.Name))
            {
                DoSomething();
            }
        }
    }

我建议我们在“Things”基类中添加一个属性,以告诉我们它是否支持X,因为Thing子类需要实现相关的功能。像这样:

public void ControlStuff()
    {
        var listOfThings = LoadThings();
        foreach (var thing in listOfThings)
        {
            if (thing.SupportsX)
            {
                DoSomething();
            }
        }
    }
class ThingBase
{
    public virtual bool SupportsX { get { return false; } }
}
class ThingA : ThingBase
{
    public override bool SupportsX { get { return true; } }
}
class ThingB : ThingBase
{
}

所以,第一种方法为什么不好是很明显的,但这被称为什么?此外,有没有比我建议的更适合这个问题的模式?


30
根据X的不同,你的建议可能会因为不同的原因与硬编码O(n^2)方法一样具有问题。你将关于X的知识强制放入基类中,因此在创建每个派生类时(无论它是否支持X)都需要这些知识。对于那些与X完全无关的“Thing”类型,"SupportsX()"方法只是公共接口中的污染。如果你有许多不同的特性(SupportsY(), SupportsZ()等),这种污染会很快变得极其严重。可以考虑使用泛型测试Supports(X)或者使用接口来标记特性支持。 - Lee
14个回答

3
如果是一个字符串,我可能会称之为“神奇字符串”。在这种情况下,我会考虑使用“神奇字符串数组”。

0

我不知道是否有一种编写代码的“模式”是不可维护或不可重用的。为什么不能直接告诉他们原因呢?


我已经实现了它,就像这样。也许这个例子会有所帮助,因为“树木遮住了森林”。谢谢。 - John Cornell
1
为什么要点赞?我认为这是一个糟糕的答案,它没有为问题提供任何帮助。解释一下为什么它不可维护或不可重用会更有帮助。现在它只是重复了问题,说“这是糟糕的代码”,任何具有至少一些面向对象技能的人都可以看到。我认为它应该是-1而不是+1。 - Mykolas Simutis
提问者询问是否存在反模式,我认为上述代码没有反模式。提问者显然知道为什么这是糟糕的代码,那我为什么要再次解释呢?与其抱怨我的回答,不如你自己提供一个答案或者补充问题。 - Cody
“在我的解释中提供帮助的参考”。实际上,他问为什么代码不好。如果没有名称,这并不意味着它不能被解释。我已经提供了自己的想法,如何向团队解释。 - Mykolas Simutis

0
为了让我理解得最清楚,最好用计算复杂度的术语来解释。绘制两张图表,显示所需的操作数量,其中一张以count(listOfThingsThatSupportX)为术语,另一张以count(listOfThings)为术语,并将其与您提出的解决方案进行比较。

0

可以使用属性而不是接口。它们可能会描述对象应该被标记为这种类型的对象,即使将其标记为此类对象并不会引入任何额外的功能。也就是说,将一个对象描述为“物品A”并不意味着所有“物品A”都具有特定接口,重要的是它们是“物品A”。这似乎更像是属性而不是接口的工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接