【发布时间】:2011-12-02 00:52:05
【问题描述】:
我正在尝试向我的团队解释为什么这是不好的做法,并且正在寻找反模式参考来帮助我解释。这是一个非常大的企业应用程序,所以这里有一个简单的例子来说明实现了什么:
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
{
}
那么,很明显为什么第一种方法是不好的做法,但是这叫什么?另外,有没有比我建议的更适合这个问题的模式?
【问题讨论】:
-
根据
X是什么,您的建议可能与硬编码 O(n^2) 方法一样有问题,但原因不同。您将 X 的知识强加到基类中,因此也强加到您创建的每个派生类中(无论它是否支持 X)。对于 X 完全不相关的Things 类型,SupportsX()方法只不过是公共接口中的污染。如果你有很多不同的功能(SupportsY()、SupportsZ()等),这种污染很快就会变得极端。考虑一个通用测试Supports(X),或者使用接口来标记功能支持。
标签: c# anti-patterns