Java Interface Instructions d'utilisation - sont des accesseurs dans une interface mauvaise?
Question
Qu'est-ce que les gens pensent des lignes directrices à utiliser dans une interface? Ce qui devrait et ne devrait pas entrer dans une interface?
Je l'ai entendu dire que, en règle générale, une interface ne doit définir le comportement et non l'Etat. Est-ce que cela signifie qu'une interface ne doit pas contenir des accesseurs?
Mon avis: Peut-être pas pour setters, mais parfois je pense que getters sont valides pour être placé dans une interface. Ceci est simplement de faire respecter les classes de mise en œuvre pour mettre en œuvre ces getters et d'indiquer ainsi que les clients sont en mesure d'appeler ces getters pour vérifier quelque chose, par exemple.
La solution
Je pense qu'il ya deux types d'interfaces déclarées en général:
- Description de service . Cela pourrait être quelque chose comme
CalculationService
. Je ne pense pas que les méthodesgetX
devrait être dans ce genre d'interface, et certainement passetX
. Ils impliquent très clairement les détails de mise en œuvre, ce qui est le travail de ce type d'interface. - modèle de données - existe uniquement à la mise en œuvre abstraite des objets de données dans le système. Celles-ci pourraient être utilisés pour aider à l'essai ou tout simplement parce que certaines personnes aussi vieux que moi se rappellent les jours où (par exemple) en utilisant un framework de persistance lié vous vers le bas pour avoir un superclasss particulier (c.-à-vous choisir d'implémenter une interface en cas vous avez activé votre couche de persistance). Je pense que d'avoir des méthodes JavaBean dans ce type d'interface est tout à fait raisonnable.
Note: les classes de collections tiennent probablement pour taper # 2
Autres conseils
Je ne vois pas pourquoi une interface ne peut pas définir des accesseurs. Par exemple, List.size()
est effectivement un getter. L'interface doit définir le comportement plutôt que la mise en œuvre bien - il ne peut pas dire comment vous allez gérer l'état, mais il peut exiger que vous pouvez l'obtenir et définir il.
interfaces de collecte sont tout état, par exemple -. Mais différentes collections peuvent stocker cet état de manière radicalement différente
EDIT: Les commentaires suggèrent que des accesseurs impliquent un simple champ est utilisé pour la sauvegarde de stockage. Je suis en désaccord avec véhémence cette implication. A mon avis, il y a une implication qu'il est « raisonnablement pas cher » pour obtenir / définir la valeur, mais pas qu'il est stocké comme un champ avec une implémentation triviale.
Il n'y a rien d'intrinsèquement mauvais getters / setters. Cependant:
- J'ai tendance à faire mes objets immuables (en premier lieu) en ce qui concerne les champs qu'ils contiennent. Pourquoi ? J'instancier la plupart des choses au cours de la phase de construction. Si je veux changer quelque chose plus tard, je relaxe ces restrictions. Donc, mes interfaces auront tendance à contenir getters, mais pas setters (il y a d'autres avantages - en particulier le filetage).
- Je veux que mes objets à faire des choses pour moi , et non l'inverse. Alors, quand l'un de mes objets acquiert un certain nombre d'apporteurs, je commence à se demander si cet objet devrait avoir plus de fonctionnalités en elle, plutôt que d'exposer toutes ses données pour quelque chose d'autre à travailler avec. Voir cette réponse pour plus de détails.
Ce sont toutes les directives, note.
Je ne pense pas un haricot devrait avoir une interface sur le dessus de celui-ci, en général. Un JavaBean est une interface au sens plus général. Une interface spécifie le contrat externe de quelque chose de plus complexe. contrat externe et sa représentation interne d'un javabean sont identiques.
Je ne dirais pas que vous ne devriez pas avoir getters dans une interface, cependant. Il est parfaitement logique d'avoir une interface ReadableDataThingie qui est mis en œuvre par DataThingieBean.
Je l'ai entendu dire que, En règle générale, une interface doit seulement définir le comportement et non l'état. Est-ce que cela signifie qu'une interface ne devrait pas contiennent des accesseurs?
Pour commencer, au moins avec Java et à l'exclusion des déclarations d'exception, vous ne pouvez pas définir le comportement complet sans état. En Java, les interfaces ne définissent pas le comportement. Ils ne peuvent pas. Ce qu'ils définissent sont des types; promesses de mettre en œuvre un ensemble de signatures de fonction peut-être avec quelques exceptions post-conditions wrt. Mais c'est tout. Comportement et de l'état sont définies par les classes de mise en œuvre de ces interfaces.
En second lieu, si accesseurs sont définies dans une interface, ils ne le comportement complet définissent pas vraiment (autre que l'on est en lecture et un pour wrt d'écriture d'une propriété.) Vous pouvez avoir un comportement complexe derrière setters et getters, mais ils ne peuvent être mises en œuvre dans les classes réelles. Il n'y a rien dans le langage Java qui peut nous permettre de définir librement le comportement dans les interfaces, sauf pour les plus restrictives des cas.
Avec cela en considération, il n'y a rien de mal - et sémantiquement syntaxiquement -. D'avoir setters et getters dans les interfaces
Si votre application est bien modélisé et le problème exige que vous disposez d'une interface définissant setters et getters, pourquoi pas. Par exemple, jetez un oeil à l'interface ServletResponse.
Maintenant, si nous regardons accesseurs du point de vue de la mise en œuvre des classes conformes aux spécifications JavaBeans, alors vous n'avez pas besoin de définir des interfaces pour eux.
Mais si vous avez des choses qui nécessitent setters et getters, comme un haricot pourrait, et qui est également nécessaire pour être branché à la compilation de type (pas d'exécution comme un haricot peut), et pour lesquels plusieurs implémentations peuvent exister , alors oui, cela demanderait une interface définissant accesseurs.
it helps.
Cette touche à l'ensemble Getter / Setter sont le sujet du mal qui est adressé à plusieurs reprises sur ce site et ailleurs.
J'ai tendance à privilégier ne pas avoir accesseurs dans l'interface, mais pour ajouter des collaborateurs utilisant des arguments du constructeur à la mise en œuvre.
Le fait que la mise en œuvre directe de quelque chose est un getter ne doit pas l'empêcher d'être dans une interface si elle doit être.
Pour en savoir plus:. API pratique design Confessions d'un architecte Java Framework (Jaroslav Tulach 2008, Apress)
je ce genre d'interfaces, par exemple, nous avons eu des cours avec des champs beginDate, endDate. Ces champs étaient dans de nombreuses classes et j'ai eu un cas d'utilisation, je dois obtenir ces dates pour des objets différents, donc j'extrait interface et était très heureux:)
En gros, si la réponse à « Ai-je besoin de connaître la valeur de [État, la propriété, whateverThignAMaGit] afin de travailler avec une instance de celui-ci? » alors oui ... les accesseurs appartiennent à l'interface.
List.size () de John ci-dessus est un exemple parfait d'un getter qui doit être définie dans une interface
accesseurs sont utilisés pour interroger l'état d'un objet - que vous pouvez vraiment éviter lors de la conception de votre interface. Lire http://www.pragprog.com/articles/tell-dont-ask