2015-10-15 93 views
7

爲什麼java.util.Iterator接口有方法remove()違反Java核心迭代器中的單一責任原則

當然有時候這種方法是必要的,並且都已經習慣了它的存在。但實際上,迭代器的主要和唯一目標只是提供訪問容器元素。當有人想爲這個界面創建他自己的實現,並且不能或不想以任何理由提供去除元素的能力時,他就會被迫拋出UnsupportedOperationException。拋出這個異常通常表明一個不太精心設計的架構或一些設計缺陷。

真的,我不明白這樣一個決定的原因。我想這將是更正確地分離特定的子接口支持可選的方法:

diagram

任何理由的版本,爲什麼remove()Iterator的一部分?這不是直接違反SOLID單一責任原則的例子嗎?

+0

實際上,您在這裏提出的「不帶刪除語義的迭代器」相當於遺留的['Enumeration'](http://docs.oracle.com/javase/8/docs/api/java/util/ Enumeration.html)接口,它被Java 1.2中的'Iterator'取代。 –

+1

除了「引入了一種新的基礎集合」之外,其他變化向量是什麼?如果您認爲SRP是「做太多事情」而不是「有太多改變的原因」,那麼您最終會遇到一些瘋狂的正常形式,其中程序中的每種方法都有自己的界面。 – Affe

回答

6

除了花哨的技術答案...請考慮時間線了。 「單一責任原則」是羅伯特馬丁在90年代中後期某個時候創造的。

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

Sun在開發早期版本的Java時很可能沒有聽說過這個概念。

當然,很多聰明人在閱讀關於它的書時都會有相同的想法......所以一位優秀的設計師可能不知道「SRP」就實施了「SRP」 - 但它也需要高度的意識揭開這一規則的所有大小違規...

+0

[Uncle Bob](https://en.wikipedia.org/wiki/Robert_Cecil_Martin)的「敏捷軟件開發:原則,模式和實踐」實際上是在2002年發佈的。 –

+0

@MickMnemonic我知道。但是當你仔細研究維基百科關於SRP的文章...你會發現你提到的這本書是基於一些文章 - 如果我沒有弄錯,那些文章從1995年開始寫! – GhostCat

+0

這一點不是術語。問題是這是否是好的解決方案。從常識和設計最佳實踐的角度出發,而不是根據任何特定的分類或抽象定義。 – kapand

3

這個設計決定在Java Collections API Design FAQ中解釋。具體來說,請參閱關於爲什麼集合不支持不變性的第一個問題,而是需要可選操作。簡而言之,他們不希望接口數量出現「爆炸式增長」。

2

這裏似乎混淆了語義。羅伯特C.馬丁把單一責任定義爲「改變的唯一原因」(SRP.pdf),而不是「只做一件事」。 SRP與的凝聚力非常相關:軟件模塊應該只包含彼此在功能上相關的東西。

考慮到這些因素,我認爲Iterator中包含的remove方法違反了SRP。在遍歷元素時,刪除元素通常是您可能想要執行的操作;這些行動基本上是一致的。此外,通過Iterator啓用刪除元素使Iterable接口(它在Java 5中添加)功能更加強大。這個特徵被用於例如很多方法在Guava's Iterables utility class

更多的信息在這個詞的歷史在this excellent article由叔叔鮑勃本人。

+0

這個問題不是綁定語義形式。從具體的原則名稱出發。那不是重點。我不應該專注於此。我對評估這個決定及其意義感興趣。畢竟,迭代器不能以其主要目的和經典定義來提供刪除操作。 – kapand