2015-10-15 6 views
7

Warum java.util.Iterator Schnittstelle hat Methode remove()?Verletzung der Single-Verantwortung-Prinzip in Iterator von Java-Core

Sicher manchmal ist diese Methode notwendig und alle haben sich an seine Anwesenheit gewöhnt. Tatsächlich besteht das Hauptziel des Iterators lediglich darin, Zugriffscontainerelemente bereitzustellen. Und wenn jemand seine eigene Implementierung für diese Schnittstelle erstellen möchte und nicht aus irgendeinem Grund die Möglichkeit haben will, ein Element zu entfernen, dann ist er gezwungen, UnsupportedOperationException zu werfen. Das Auslösen dieser Ausnahme weist normalerweise auf eine nicht allzu durchdachte Architektur oder auf einige Designfehler hin.

Wirklich verstehe ich nicht die Gründe für eine solche Entscheidung. Und ich denke, es wäre mehr richtig einen bestimmten Subschnittstelle trennt die optionale Methode zu unterstützen:

diagram

keine begründete Version warum remove() Teil der Iterator ist? Ist das nicht ein Beispiel für eine direkte Verletzung des Grundsatzes der einheitlichen Verantwortung von SOLID?

+0

Eigentlich ist das „Iterator ohne remove-Semantik“, die Sie hier vorschlagen, ist gleichbedeutend mit dem Erbe [ 'Enumeration'] (http://docs.oracle.com/javase/8/docs/api/java/util/ Enumeration.html) Schnittstelle, die in Java 1.2 durch 'Iterator' ersetzt wurde. –

+1

Was ist der andere Veränderungsvektor neben "Ein neuer Typ der zugrunde liegenden Sammlung wird eingeführt"? Wenn Sie SRP als "zu viele Dinge" statt "zu viele Gründe, um sich zu ändern" denken, werden Sie irgendwann in eine verrückte normale Form geraten, wo jede Methode in Ihrem Programm eine eigene Schnittstelle hat. – Affe

Antwort

6

Zusätzlich zu ausgefallenen technischen Antworten ... bitte beachten Sie auch die Zeitleiste. Das "Single-Responsibility-Prinzip" wurde von Robert Martin irgendwann Mitte/Ende der 90er Jahre geprägt.

Die Java-Iterator-Schnittstelle ist mit Java 1.2 entstanden; so um 1998

Es ist sehr viel möglich, dass die Leute bei Sun noch nie von diesem Konzept gehört hatten, während auf den frühen Versionen von Java arbeiten.

Natürlich haben viele intelligente Leute die gleichen Ideen, ohne ein Buch darüber zu lesen ... also könnte ein guter Designer "SRP" implementiert haben, ohne von "SRP" zu wissen - aber es erfordert auch ein hohes Maß an Bewusstsein zu enthüllen alle großen und kleinen Verletzungen dieser Regel ...

+0

"Agile Software-Entwicklung: Prinzipien, Muster und Praktiken" von [Onkel Bob] (https://en.wikipedia.org/wiki/Robert_Cecil_Martin) wurde tatsächlich im Jahr 2002 veröffentlicht. –

+0

@MickMnemonic Ich weiß. Aber wenn Sie den Wikipedia-Artikel zu SRP sorgfältig studieren, werden Sie feststellen, dass das Buch, das Sie erwähnen, auf einigen Artikeln basiert - und diese wurden ab 1995 geschrieben, wenn ich mich nicht irre! – GhostCat

+0

Der Punkt ist nicht die Terminologie. Die Frage ist, ob das die gute Lösung ist. Aus der Sicht des gesunden Menschenverstandes und der besten Design-Praxis, und nicht nach einer bestimmten Klassifizierung oder abstrakten Definitionen. – kapand

3

Diese Design-Entscheidung wird in der Java Collections API Design FAQ erläutert. Insbesondere finden Sie in der ersten Frage, warum Sammlungen nicht immutability unterstützen und stattdessen optionale Vorgänge erfordern. Die kurze Antwort ist, dass sie keine "Explosion" in der Anzahl der Schnittstellen wollten.

2

Es scheint hier eine Verwechslung der Semantik zu geben. Robert C. Martin definiert Single Responsibility als einen "einzigen Grund zur Veränderung" (SRP.pdf), nicht als "nur eine einzige Sache zu tun". SRP ist sehr verwandt mit Zusammenhalt: ein Softwaremodul sollte nur Dinge enthalten, die funktional miteinander verwandt sind.

Mit diesen Dingen im Hinterkopf, ich glaube nicht, dass die remove Methode in Iterator enthalten verletzt die SRP. Das Entfernen eines Elements ist oft etwas, das Sie während der Iteration über die Elemente ausführen möchten. Die Operationen sind im Wesentlichen zusammenhängend. Durch das Aktivieren der Entfernung von Elementen über Iterator wird auch die Schnittstelle Iterable (die in Java 5 hinzugefügt wurde) wesentlich leistungsfähiger. Dieses Merkmal wird z.B. viele der Methoden in Guava's Iterables utility class.

Mehr Informationen über die Geschichte des Begriffs in this excellent article von Uncle Bob selbst.

+0

Das Problem ist nicht gebundene semantische Formen. Verlassen Sie die spezifischen Namen der Prinzipien. Das ist nicht der Punkt. Ich hätte mich nicht darauf konzentrieren sollen. Ich bin daran interessiert, diese Entscheidung und ihren Sinn zu bewerten. Schließlich muss der Iterator die Operation remove nicht nach ihrem primären Zweck und der klassischen Definition bereitstellen. – kapand