2015-10-15 1 views
7

Pourquoi l'interface java.util.Iterator a la méthode remove()?Violation du principe de responsabilité unique dans Iterator à partir du cœur Java

Certes, cette méthode est parfois nécessaire et tous se sont habitués à sa présence. Mais en fait, l'objectif principal et unique de l'itérateur est simplement de fournir des éléments de conteneur d'accès. Et quand quelqu'un veut créer sa propre implémentation pour cette interface, et ne peut ou ne veut pour aucune raison fournir la possibilité de supprimer un élément, alors il est forcé de lancer UnsupportedOperationException. Et le lancement de cette exception indique généralement une architecture pas trop bien pensée ou quelques défauts de conception. Vraiment je ne comprends pas les raisons d'une telle décision.

Et je suppose que ce serait plus correctement séparer une sous-interface spécifique pour soutenir la méthode facultative:

diagram

Toutes les versions raisonnés pourquoi remove() fait partie du Iterator? Cet exemple de violation directe du principe de la responsabilité unique n'est-il pas SOLID?

+0

En fait, le "itérateur sans suppression-sémantique" que vous proposez ici est équivalent à l'héritage ['Enumeration'] (http://docs.oracle.com/javase/8/docs/api/java/util/ Enumeration.html), qui a été remplacé par 'Iterator' dans Java 1.2. –

+1

Quel est l'autre vecteur de changement en plus de "Un nouveau type de collection sous-jacente est introduit"? Si vous considérez SRP comme "faire trop de choses" au lieu de "avoir trop de raisons de changer", vous finirez par tomber dans une forme normale folle où chaque méthode de votre programme a sa propre interface. – Affe

Répondre

6

En plus de réponses techniques de fantaisie ... s'il vous plaît considérer la chronologie aussi. Le «principe de responsabilité unique» a été inventé par Robert Martin à un moment donné au milieu et à la fin des années 90.

L'interface Java itérateur a été créée avec Java 1.2; donc autour de 1998.

Il est très possible que les gens de Sun n'aient jamais entendu parler de ce concept en travaillant sur les premières versions de Java. Bien sûr, beaucoup de gens intelligents ont les mêmes idées sans lire un livre à ce sujet ... donc un bon concepteur aurait pu mettre en œuvre "SRP" sans connaître le "SRP" - mais cela nécessite aussi un haut degré de conscience pour dévoiler toutes les grandes et petites violations de cette règle ...

+0

"Développement de logiciels agiles: principes, modèles et pratiques" par [Oncle Bob] (https://en.wikipedia.org/wiki/Robert_Cecil_Martin) a été publié en 2002. –

+0

@MickMnemonic Je sais. Mais quand vous étudiez attentivement l'article de wikipedia sur SRP ... vous constaterez que le livre que vous mentionnez est basé sur quelques articles - et ceux-ci ont été écrits à partir de 1995 si je ne me trompe pas! – GhostCat

+0

Le point n'est pas la terminologie. La question est de savoir si c'est la bonne solution. Du point de vue du bon sens et de la meilleure pratique en matière de conception, et non selon une classification particulière ou des définitions abstraites. – kapand

3

Cette décision de conception est expliquée dans le Java Collections API Design FAQ. Plus précisément, consultez la première question sur les raisons pour lesquelles les collections ne prennent pas en charge l'immuabilité et requièrent plutôt des opérations facultatives. La réponse courte est qu'ils ne voulaient pas "une explosion" du nombre d'interfaces.

2

Il semble y avoir un mélange de sémantique ici. Robert C. Martin définit la Responsabilité Unique comme une «raison unique de changer» (SRP.pdf), et non comme «faire une seule chose». SRP est très liée à cohésion: un module logiciel ne doit contenir que des choses fonctionnellement liées les unes aux autres. Avec ces choses à l'esprit, je ne pense pas qu'avoir la méthode remove incluse dans Iterator viole le SRP. Supprimer un élément est souvent quelque chose que vous pourriez vouloir faire en itérant sur les éléments; les opérations sont essentiellement cohésives. En outre, l'activation de la suppression des éléments via Iterator rend l'interface Iterable (qui a été ajoutée dans Java 5) beaucoup plus puissante. Cette caractéristique est utilisée par ex. beaucoup de méthodes dans Guava's Iterables utility class.

Plus d'informations sur l'histoire du terme dans this excellent article par Uncle Bob lui-même.

+0

Le problème n'est pas lié aux formes sémantiques. Partir des noms spécifiques des principes. Ce n'est pas le propos. Je n'aurais pas dû me concentrer là-dessus. Je suis intéressé par l'évaluation de cette décision et de son sens. Après tout, l'itérateur ne doit pas fournir d'opération de suppression par son but principal et la définition classique. – kapand