Cet article prétend qu'une classe de données est une "odeur de code". La raison:
C'est une chose normale quand une classe nouvellement créée ne contient que quelques champs publics (et peut-être même une poignée de getters / setters). Mais la vraie puissance des objets est qu'ils peuvent contenir des types de comportement ou des opérations sur leurs données.
Pourquoi un objet ne contient-il que des données? Si la responsabilité principale de la classe est de représenter les données, n'ajouterait-on pas des méthodes qui opèrent sur les données en brisant le principe de responsabilité unique ?
Réponses:
Il n'y a absolument rien de mal à avoir des objets de données purs. Franchement, l'auteur de la pièce ne sait pas de quoi il parle.
Une telle pensée découle d'une vieille idée, échouée, que "true OO" est la meilleure façon de programmer et que "true OO" est tout au sujet de "modèles de données riches" où l'on mélange les données et les fonctionnalités.
La réalité nous a montré qu'en réalité l'inverse est vrai, en particulier dans ce monde de solutions multi-thread. Les fonctions pures, combinées à des objets de données immuables, constituent un moyen manifestement meilleur de coder.
la source
Il n'y a absolument rien de mal à avoir des objets de données purs. L'auteur a une opinion non partagée par les développeurs de logiciels que je connais.
Surtout pour le mappage de bases de données, vous avez en général des classes d'entités qui ne contiennent que les champs stockés dans la base de données et les getters et setters. Wikipedia Hibernate (framework)
L'idée de trou des beans Java utilisée par de nombreux outils / frameworks est basée sur des classes de données appelées beans qui ne contiennent que des champs et les getters et setters associés. Wikipdia JavaBeans
Fazit:
Si quelqu'un prétend que quelque chose est «mauvais» ou «une odeur de code», vous devriez toujours chercher les raisons données. Si les raisons ne vous convaincent pas, demandez à quelqu'un d'autre de meilleures raisons ou une opinion différente. (Comme vous l'avez fait dans ce forum)
la source
Un bon argument pourquoi par Martin Fowler:
"Tell-Don't-Ask est un principe qui aide les gens à se rappeler que l'orientation objet consiste à regrouper des données avec les fonctions qui opèrent sur ces données. Cela nous rappelle qu'au lieu de demander des données à un objet et d'agir sur ces données, nous devrait plutôt indiquer à un objet ce qu'il doit faire. Cela encourage à déplacer le comportement dans un objet pour aller avec les données. "
https://martinfowler.com/bliki/TellDontAsk.html
la source
baz
un paramètre à une méthode statique, mais pour ce faire, vous devez d'abord demander à l'objet de le faire. Peut-être que dans un paradigme de programmation où les méthodes étaient primaires (comme, par exemple, la programmation fonctionnelle), cela a du sens, mais dans un environnement OO, ce n'est absolument pas le cas, car les objets sont primaires et doivent contenir à la fois les données et les fonctions pour agir en conséquence. Votre affirmation selon laquelle la suppression de la méthode de l'objet a augmenté l'encapsulation est également exactement à l'envers , pour autant que je sache, car cela signifie que vous avez maintenant unebaz
apparence en dehors de l'objet.Ce que vous devez comprendre, c'est qu'il existe deux types d'objets:
Objets qui ont un comportement . Ceux-ci devraient s'abstenir de donner au public l'accès à la plupart des membres de leurs données. Je n'attends que très peu de méthodes d'accesseur définies pour celles-ci.
Un exemple serait une expression régulière compilée: l'objet est créé pour fournir un certain comportement (pour faire correspondre une chaîne à une expression rationnelle spécifique et pour signaler les correspondances (partielles)), mais la façon dont l'expression régulière compilée fait son travail n'est pas celle de l'utilisateur. affaires.
La plupart des classes que j'écris appartiennent à cette catégorie.
Des objets qui ne sont vraiment que des données . Ceux-ci devraient simplement déclarer tous leurs membres publics (ou fournir l'ensemble complet d'accesseurs pour eux).
Un exemple serait une classe
Point2D
. Il n'y a absolument aucun invariant qui doit être assuré pour les membres de cette classe, et les utilisateurs devraient pouvoir simplement accéder aux données viamyPoint.x
etmyPoint.y
.Personnellement, je n'utilise pas beaucoup ces classes, mais je suppose qu'il n'y a pas de plus gros morceau de code que j'ai écrit qui n'utilise pas une telle classe quelque part.
Pour devenir compétent en orientation d'objet, il faut comprendre que cette distinction existe et apprendre à classer la fonction d'une classe dans l'une de ces deux catégories.
Si vous codez en C ++, vous pouvez rendre cette distinction explicite en utilisant
class
pour la première catégorie d'objets etstruct
pour la seconde. Bien sûr, les deux sont équivalents, sauf que celaclass
signifie que tous les membres sont privés par défaut, alors questruct
tous les membres sont publics par défaut. C'est exactement le genre d'informations que vous souhaitez communiquer.la source