从Java核心违反迭代器中的单一责任原则

时间:2015-10-15 23:33:02

标签: java oop design-patterns iterator solid-principles

为什么java.util.Iterator接口有方法remove()

当然,有时这种方法是必要的,所有人都习惯了它的存在。但实际上迭代器的主要和唯一目的只是提供访问容器元素。当有人想为这个界面创建自己的实现,并且不能或不想以任何理由提供删除元素的能力时,他就被迫抛出UnsupportedOperationException。抛出异常通常表明架构设计不够深入或设计存在缺陷。

我真的不明白做出这样决定的原因。我想这将更正确地分离特定的子接口以支持可选方法:

diagram

任何合理的版本remove()Iterator的一部分?这个直接违反SOLID的单一责任原则的例子不是吗?

3 个答案:

答案 0 :(得分:6)

除了花哨的技术答案之外......请考虑时间表。 “单一责任原则”是由罗伯特·马丁在90年代中后期的某个时刻创造出来的。

Java迭代器接口与Java 1.2一起出现;所以在1998年左右。

在处理早期版本的Java时,Sun的人们很可能从未听说过这个概念。

当然,许多聪明的人在没有阅读有关它的书的情况下也有相同的想法...所以一个优秀的设计师可能已经实施了“SRP”而不知道“SRP” - 但它也需要高度的意识到公布所有违反此规则的大小违规行为......

答案 1 :(得分:3)

此设计决定在Java Collections API Design FAQ中解释。具体来说,请参阅第一个问题,了解为什么集合不支持不变性,而是需要可选操作。简短的回答是,他们并不想要"爆炸"在接口数量。

答案 2 :(得分:2)

这里似乎混淆了语义。 Robert C. Martin将单一责任定义为“改变的唯一理由”(SRP.pdf),而不是“只做一件事”。 SRP与 cohesion 非常相关:软件模块应该只包含功能相关的东西。

考虑到这些因素,我不认为remove中包含的Iterator方法违反了SRP。在迭代元素时,通常需要删除元素;这些行动本质上是有凝聚力的。此外,通过Iterator启用元素删除使得Iterable接口(在Java 5中添加)更加强大。该特征用于例如Guava's Iterables utility class中的许多方法。

鲍勃叔叔自己在this excellent article中关于这个词的历史的更多信息。