it-swarm.dev

Warum wurden Java Sammlungen mit "optionalen Methoden" in der Schnittstelle implementiert?

Bei meiner ersten Implementierung zur Erweiterung des Java - Sammlungsframeworks war ich ziemlich überrascht, dass die Sammlungsschnittstelle als optional deklarierte Methoden enthält. Es wird erwartet, dass der Implementierer UnsupportedOperationExceptions auslöst, wenn er nicht unterstützt wird. Dies fiel mir sofort auf eine schlechte Wahl für das API-Design.

Nachdem er viel von Joshua Blochs ausgezeichnetem "Effective Java" -Buch gelesen und später erfahren hatte, dass er möglicherweise für diese Entscheidungen verantwortlich ist, schien es nicht mit den in dem Buch vertretenen Prinzipien übereinzustimmen. Ich würde denken, dass das Deklarieren von zwei Schnittstellen: Collection und MutableCollection, die Collection mit den "optionalen" Methoden erweitern, zu einem viel besser wartbaren Client-Code geführt hätte.

Es gibt eine hervorragende Zusammenfassung der Probleme hier .

Gab es einen guten Grund, warum optionale Methoden anstelle der Implementierung der beiden Schnittstellen gewählt wurden?

69
glenviewjeff

Die Antwort FAQ liefert die Antwort. Kurz gesagt, sie sahen eine potenzielle kombinatorische Explosion der benötigten Schnittstellen mit modifizierbarer, nicht modifizierbarer Ansicht, nur Löschen, nur Hinzufügen, fester Länge, unveränderlich (für Threading) usw. für jeden möglichen Satz implementierter Optionsmethoden.

28
ratchet freak

Es klingt für mich wie das Interface Segregation Principle war damals nicht so gut erforscht wie heute; Diese Art, Dinge zu tun (dh Ihre Schnittstelle enthält alle möglichen Operationen und Sie haben "entartete" Methoden, die Ausnahmen für diejenigen auslösen, die Sie nicht benötigen), war beliebt, bevor SOLID und ISP wurde die De-facto-Standard für Qualitätscode.

10
Wayne Molina

Während einige Leute "optionale Methoden" verabscheuen, bieten sie in vielen Fällen eine bessere Semantik als stark getrennte Schnittstellen. Unter anderem berücksichtigen sie die Möglichkeiten, dass ein Objekt in seiner Lebensdauer Fähigkeiten oder Eigenschaften erlangen kann oder dass ein Objekt (insbesondere ein Wrapper-Objekt) möglicherweise nicht weiß, wann es erstellt wird, welche genauen Fähigkeiten es melden soll.

Während ich die Java - Sammlungsklassen-Paragone für gutes Design kaum nennen werde, würde ich vorschlagen, dass ein gutes Sammlungsframework bei seiner Gründung eine große Anzahl optionaler Methoden enthalten sollte zusammen mit Möglichkeiten von Fragen einer Sammlung nach ihren Eigenschaften und Fähigkeiten. Ein solches Design ermöglicht die Verwendung einer einzelnen Wrapper-Klasse mit einer Vielzahl von Sammlungen, ohne versehentlich die Fähigkeiten der zugrunde liegenden Sammlung zu verschleiern. Wenn Methoden nicht optional wären, wäre dies der Fall Es muss erforderlich sein, für jede Kombination von Funktionen, die Sammlungen unterstützen, eine andere Wrapper-Klasse zu haben. Andernfalls müssen einige Wrapper in bestimmten Situationen unbrauchbar sein.

Wenn eine Sammlung beispielsweise das Schreiben eines Elements nach Index oder das Anhängen von Elementen am Ende unterstützt, das Einfügen von Elementen in der Mitte jedoch nicht unterstützt, benötigt Code, der es in einen Wrapper einkapseln möchte, der alle darauf ausgeführten Aktionen protokolliert, eine Version des Protokollierungs-Wrappers, der die genaue Kombination der unterstützten Fähigkeiten vorsah, oder wenn keiner verfügbar war, müsste ein Wrapper verwendet werden, der entweder Anhängen oder Schreiben nach Index unterstützt, aber nicht beide. Wenn jedoch eine einheitliche Auflistungsschnittstelle alle drei Methoden als "optional" bereitstellt, dann aber Methoden enthält, die angeben, welche der optionalen Methoden verwendet werden können, kann eine einzelne Wrapper-Klasse Sammlungen verarbeiten, die eine beliebige Kombination von Funktionen implementieren. Auf die Frage, welche Funktionen unterstützt werden, kann ein Wrapper einfach melden, was auch immer die gekapselte Sammlung unterstützt.

Beachten Sie, dass das Vorhandensein von "optionalen Fähigkeiten" in einigen Fällen es aggregierten Sammlungen ermöglichen kann, bestimmte Funktionen auf eine Weise zu implementieren, die viel effizienter ist, als dies möglich wäre, wenn Fähigkeiten durch das Vorhandensein von Implementierungen definiert würden. Angenommen, eine concatenate -Methode wurde verwendet, um eine zusammengesetzte Sammlung aus zwei anderen zu bilden, von denen die erste zufällig eine ArrayList mit 1.000.000 Elementen war und die letzte eine Sammlung mit zwanzig Elementen, die nur möglich war von Anfang an iteriert werden. Wenn die zusammengesetzte Sammlung nach dem 1.000.013. Element (Index 1.000.012) gefragt würde, könnte sie die ArrayList fragen, wie viele Elemente sie enthält (dh 1.000.000), diese vom angeforderten Index subtrahieren (12 ergeben), zwölf Elemente vom zweiten lesen und überspringen Sammlung, und geben Sie dann das nächste Element zurück.

In einer solchen Situation wäre es immer noch viel schneller, die zusammengesetzte Sammlung nach dem 1.000.013. Element zu fragen, obwohl die zusammengesetzte Sammlung keine sofortige Möglichkeit hätte, ein Element nach Index zurückzugeben, als 1.000.013 Elemente einzeln daraus zu lesen und alle bis auf das letzte zu ignorieren einer.

4
supercat