【问题标题】:Interface Segregation Principle - How to decide what to segregate?接口隔离原则 - 如何决定隔离什么?
【发布时间】:2016-10-19 16:35:47
【问题描述】:

我相信这个问题是不言自明的。我宁愿把更多的注意力放在例子上来支持问题。

public interface IEnumerable
{
    IEnumerator GetEnumerator();
}

public interface ICollection : IEnumerable
{
    void CopyTo(Array array, int index);
    int Count { get; }
    Object SyncRoot { get; }
    bool IsSynchronized { get; }
}

public interface IList : ICollection
{
    Object this[int index] { get; set; }
    int Add(Object value);
    bool Contains(Object value);
    void Clear();
    bool IsReadOnly { get; }
    bool IsFixedSize { get; }
    int IndexOf(Object value);
    void Insert(int index, Object value);
    void Remove(Object value);
    void RemoveAt(int index);
}

很明显IEnumerable 是独立的,只允许循环遍历集合。但我不明白他们为什么将ICollection 和IList 分开?即使它们是一个,IList 也不会变胖,因为任何集合总是需要这种行为?

我看到this 帖子说,如果客户端只需要循环项目,您的 API 将返回 IEnumerable,如果只需要只读访问权限,则返回 ICollection 等等。

MSFT 为何如此完美地应用 ISP,以至于这些年来从未引起任何问题?

应用 ISP 是基于客户端代码需求的持续过程还是一次性应用程序?如果 ISP 只应用一次,那么我的问题在于帖子标题本身。

【问题讨论】:

  • 我不确定是否会使用 .NET 类型作为最佳实践示例。
  • 基于示例我会问为什么 IList 没有分成 2 个或更多部分。 Add+Remove 可能低于 At 和 [] 方法。

标签: c# interface-segregation-principle


【解决方案1】:

我不明白他们为什么将ICollection 和IList 分开?

IList 是一个集合,其中通过索引获取项目是合乎逻辑的。将其分离为子接口是为了认识到存在未定义索引的其他集合这一事实。 ISet 就是这样一个集合的例子。

合并ICollection 和IList 会对一个人以干净的方式定义ISet 的能力产生负面影响,因为必须实现这四种方法:

this[int index]
int IndexOf(Object value)
void Insert(int index, Object value)
void RemoveAt(int index)

另一方面,人们可以合理地争论方法

int Add(Object value);
bool Contains(Object value);
void Clear();
bool IsReadOnly { get; }
bool IsFixedSize { get; }
void Remove(Object value);

可能属于ICollection接口。

接口隔离原则 - 如何决定隔离什么?

回想起来,当类就位时,决定要隔离什么的任务要容易得多。查看是否需要任何类来引发未实现的异常。这些方法是移动到需要引入的子接口的主要候选方法。

例如,考虑将IList 方法移至ICollection 开始设计,并且没有IList 子接口。你可以通过这两个接口成功构建List和LinkedList类。

现在考虑将HashSet 添加到组合中。该类必须实现四个与集合集合格格不入的方法,这表明您应该考虑添加一个或两个子接口——一个用于列表,另一个用于集合。

在你有任何类之前决定隔离要困难得多,因为你的接口倾向于满足需要使用它的特定类的需求。以扁平化的界面结构开始,并在后续版本中通过重构对其进行扩展的情况并不少见。

【讨论】:

  • 酷,我现在越来越清楚了。实际问题 - 接口隔离原则 - 如何决定隔离什么? 在 ISP 期间应该考虑的任何关键点?
  • 我认为 ISP 违规最明显的“气味”,以及关于如何决定要隔离什么的明确提示,是一个类实现了一个接口以及一个或多个方法最终抛出一个'NotImplementedException' 因为它只与界面的某些部分有关。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-11-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-03-04
  • 2021-11-12
相关资源
最近更新 更多