Contexte
Je lis le "Clean Code book", et, en parallèle, je travaille sur des objets calisthéniques Kata comme le compte bancaire, et je suis coincé sur cette règle:
La 9ème règle des objets calisthéniques est que nous n'utilisons pas de getter ou de setters.
Cela semble assez amusant et je suis d'accord avec ce principe. De plus, à la page 98-99 de Clean Code, l'auteur explique que les getters / setters brisent l'abstraction, et que nous n'avons pas à demander notre objet, mais nous devons le dire.
Cela est parfaitement logique dans mon esprit et je suis entièrement d'accord avec ce principe. Le problème vient en pratique.
Le contexte
Par exemple, j'ai une application dans laquelle je dois lister certains utilisateurs et afficher les détails de l'utilisateur.
Mon utilisateur est composé de:
-> Name
--> Firstname --> String
--> Lastname --> String
-> PostalAddress
--> Street --> String
--> PostalCode --> String
Problème
Comment puis-je faire ou que puis-je faire pour éviter les getters lorsque je n'ai besoin que d'afficher une information simple ( et je dois confirmer que je n'ai pas besoin d'opération supplémentaire sur ce champ particulier ) pour afficher la valeur Firstname dans un simple ( prise en charge de sortie aléatoire?
Ce qui me vient à l'esprit
Une solution consiste à faire:
user.getName().getFirstName().getStringValue()
Ce qui est totalement terrible, enfreignant de nombreuses règles des objets calisthéniques et enfreignant la loi Demeter.
Un autre serait quelque chose comme:
String firstName = user.provideFirstnameForOutput();
// That would have called in the user object =>
String firstName = name.provideFirstnameForOutput();
// That would have called in the name object =>
String firstName = firstname.provideFirstnameForOutput();
Mais je ne me sens pas à l'aise avec cette solution, qui ne semble être qu'un "accesseur d'ordre supérieur" comme contourner le getter / setter standard avec une méthode qui ne vise qu'à correspondre à la loi de Demeter ...
Une idée ?
la source
Une direction à penser serait de fournir une fonction membre de formatage de chaîne générique, plutôt que de donner accès aux données brutes. Quelque chose comme ça:
Vous voyez, avec cette approche, vous n'êtes pas limité à simplement fournir les données complètes telles quelles, vous pouvez fournir des moyens de transformer les données de manière pratique et significative. Par exemple, vous devrez peut-être jouer des tours avec la casse des personnages:
Vous pouvez également définir une fois certains formats couramment utilisés, éventuellement complexes, par exemple, par exemple
La beauté de cette approche est qu'elle garde les chaînes individuelles internes à la
User
classe, tout en fournissant beaucoup plus de fonctionnalités au code appelant. Cependant, l'inconvénient est que vous devez implémenter le mécanisme de création de modèles dansformatDescription()
lequel se trouvent quelques lignes de code.En tant que tel, cela pourrait être une exagération totale: n'oubliez jamais que les principes de programmation ne sont que des lignes directrices. Et chaque fois que suivre un autre principe viole le principe KISS, il est probablement préférable de le faire simplement. Donc, à moins que vous n'ayez au moins besoin d'un tel membre de mise en forme, je ne prendrais pas la peine de l'implémenter par souci de simplicité, en utilisant l'approche basée sur les accesseurs.
la source
User
objet d'analyser et de compiler / interpréter un langage de template?User
classe doit implémenter cette fonctionnalité elle-même. Si je n'avais que deux classes qui avaient besoin d'une telle fonctionnalité, vous pourriez parier sur moi en intégrant le mécanisme de remplacement de modèle dans sa propre classe. Ceci est censé être un exemple de la façon dont vous pouvez élever l'abstraction quiUser
fournit à un niveau où elle est en fait plus qu'un simple conteneur de données. Et je crois que c'est à cela qu'il faut éviter les accesseurs: faire de la POO au lieu de gérer un tas destruct
s.