【发布时间】:2011-09-15 08:59:07
【问题描述】:
我目前遇到了一个设计问题。
假设有一个组件的层次结构。这些组件中的每一个都派生自一个抽象的Component 类型,看起来像这样:
public abstract class Component
{
public abstract Component Parent { get; }
public abstract ComponentCollection Children { get; }
}
现在我想为这些组件添加一些可选功能,让我们以能够在组件层次结构中搜索并在层次结构中选择组件为例。
像这样在基类中提供这些可选功能是否被认为是不好的做法:
public abstract class Component
{
// Other members
public abstract bool IsSearchable { get; }
public abstract bool Search(string searchTerm);
public abstract bool IsSelectable { get; }
public abstract bool Select();
}
虽然“搜索能力”和“选择能力”在派生组件中由例如使用策略模式?
在我看来,这似乎违反了 SRP,但在我看来,唯一的选择是为每个可选功能提供一个接口,并且只在支持此功能的组件上实现它。
在我看来,这样做的缺点是每次我想检查组件是否提供特定功能时都必须编写这样的代码:
public bool Search(Component component, string searchTerm)
{
ISearchable searchable = component as ISearchable;
if(searchable != null)
{
searchable.Search(searchTerm);
}
}
您会选择哪种策略,或者您有什么更好的想法?
提前致谢!
【问题讨论】:
-
为什么你指出的缺点与你当前的代码有很大的不同,它必须首先检查 component.IsSearchable()?
-
嗯,这是我不确定的。就我个人而言,我会考虑检查属性比检查对象的类型更干净(并且可能更快)。
-
从概念上讲,对象的类型是其属性之一(一般意义上),所以这不是问题。性能可能是一个问题,可能会使用 C++ 之类的语言,但可能不会使用 Java 或 C#。还要考虑拥有 ISearchable 接口的好处 - 您可能也拥有可搜索的非组件。
-
@MadKeithV:这是真的,但在某些情况下,有人应该知道她可以将
Component转换为ISearchable。在我看来,这不是很好的声明性。 -
@Florian - 他们可以查看类声明并看到 Component 是从 ISearchable 派生的(如果所有组件都具有 ISearchable 的默认实现)。这与查看类接口查看成员函数 IsSearchable 等没有什么不同。
标签: components single-responsibility-principle coupling