Vous ne pouvez pas écrire du bon code sans les getters.
La raison n'est pas parce que les getters ne cassent pas l'encapsulation, ils le font. Ce n'est pas parce que les getters ne tentent pas les gens de ne pas prendre la peine de suivre la POO, ce qui leur ferait mettre des méthodes avec les données sur lesquelles ils agissent. Ils font. Non, vous avez besoin de getters à cause des limites.
Les idées d'encapsulation et de conservation des méthodes avec les données sur lesquelles elles agissent ne fonctionnent tout simplement pas lorsque vous rencontrez une limite qui vous empêche de déplacer une méthode et vous oblige donc à déplacer des données.
C'est vraiment aussi simple que cela. Si vous utilisez des getters quand il n'y a pas de limite, vous finissez par ne pas avoir de vrais objets. Tout commence à tendre à la procédure. Ce qui fonctionne aussi bien que jamais.
La vraie POO n'est pas quelque chose que vous pouvez répandre partout. Cela ne fonctionne que dans ces limites.
Ces frontières ne sont pas minces. Ils contiennent du code. Ce code ne peut pas être OOP. Il ne peut pas non plus être fonctionnel. Non, ce code a nos idéaux dépouillés de sorte qu'il puisse faire face à la dure réalité.
Michael Fetters a appelé ce fascia de code après ce tissu conjonctif blanc qui maintient ensemble des sections d'une orange.
C'est une merveilleuse façon d'y penser. Cela explique pourquoi il est acceptable d'avoir les deux types de code dans la même base de code. Sans cette perspective, de nombreux nouveaux programmeurs s'accrochent durement à leurs idéaux, puis ont le cœur brisé et abandonnent ces idéaux lorsqu'ils atteignent leur première frontière.
Les idéaux ne fonctionnent qu'à leur place. Ne les abandonnez pas simplement parce qu'ils ne fonctionnent pas partout. Utilisez-les là où ils travaillent. Cet endroit est la partie juteuse que le fascia protège.
Un exemple simple de frontière est une collection. Cela contient quelque chose et n'a aucune idée de ce que c'est. Comment un concepteur de collection peut-il déplacer la fonctionnalité comportementale de l'objet détenu dans la collection alors qu'il n'a aucune idée de ce qu'il va contenir? Tu ne peux pas. Vous êtes contre une frontière. C'est pourquoi les collections ont des getters.
Maintenant, si vous le saviez, vous pourriez modifier ce comportement et éviter de bouger. Quand vous savez, vous devriez. Tu ne sais pas toujours.
Certaines personnes appellent cela simplement pragmatique. Et c'est. Mais c'est bien de savoir pourquoi nous devons être pragmatiques.
Vous avez dit que vous ne vouliez pas entendre d'arguments sémantiques et que vous sembliez préconiser de mettre des «getters sensés» partout. Vous demandez que cette idée soit contestée. Je pense que je peux montrer que l'idée a des problèmes avec la façon dont vous l'avez formulée. Mais je pense aussi que je sais d'où tu viens parce que j'y suis allé.
Si vous voulez des getters partout, regardez Python. Il n'y a pas de mot clé privé. Pourtant, Python fonctionne très bien. Comment? Ils utilisent une astuce sémantique. Ils nomment tout ce qui est censé être privé avec un soulignement de premier plan. Vous êtes même autorisé à en lire à condition d'en assumer la responsabilité. "Nous sommes tous des adultes ici", disent-ils souvent.
Alors, quelle est la différence entre cela et simplement mettre des getters sur tout en Java ou C #? Désolé mais c'est de la sémantique. Les conventions Pythons soulignent clairement que vous fouillez derrière la porte réservée aux employés. Slap getters sur tout et vous perdez ce signal. Avec la réflexion, vous auriez pu de toute façon dépouillé le privé et ne pas avoir perdu le signal sémantique. Il n'y a tout simplement aucun argument structurel à faire valoir ici.
Il nous reste donc à décider où accrocher le panneau "Employés uniquement". Qu'est-ce qui devrait être considéré comme privé? Vous appelez cela des «getters sensés». Comme je l'ai dit, la meilleure justification pour un getter est une frontière qui nous éloigne de nos idéaux. Cela ne devrait pas aboutir à des getters sur tout. Quand cela aboutit à un getter, vous devriez envisager de déplacer le comportement plus loin dans le morceau juteux où vous pouvez le protéger.
Cette séparation a donné lieu à quelques termes. Un objet de transfert de données ou DTO, ne possède aucun comportement. Les seules méthodes sont des getters et parfois des setters, parfois un constructeur. Ce nom est regrettable car ce n'est pas du tout un véritable objet. Les getters et setters ne sont en fait que du débogage de code qui vous donne un endroit pour définir un point d'arrêt. Si ce n'était pas pour ce besoin, ils ne seraient qu'un tas de champs publics. En C ++, nous les appelions des structs. La seule différence qu'ils avaient d'une classe C ++ était qu'ils étaient par défaut public.
Les DTO sont agréables parce que vous pouvez les jeter sur un mur d'enceinte et conserver vos autres méthodes en toute sécurité dans un bel objet de comportement juteux. Un vrai objet. Sans getters pour violer, c'est l'encapsulation. Mes objets comportementaux peuvent manger des DTO en les utilisant comme objets paramètres . Parfois, je dois en faire une copie défensive pour empêcher un état mutable partagé . Je ne diffuse pas de DTO mutables à l'intérieur de la partie juteuse à l'intérieur de la frontière. Je les résume. Je les cache. Et quand je rencontre enfin une nouvelle frontière, je tourne un nouveau DTO et je le jette sur le mur, ce qui en fait le problème de quelqu'un d'autre.
Mais vous voulez fournir des getters qui expriment l'identité. Eh bien, félicitations, vous avez trouvé une limite. Les entités ont une identité qui dépasse leur référence. Autrement dit, au-delà de leur adresse mémoire. Il faut donc le stocker quelque part. Et quelque chose doit pouvoir se référer à cette chose par son identité. Un getter qui exprime une identité est parfaitement raisonnable. Une pile de code qui utilise ce getter pour prendre des décisions que l'entité aurait pu prendre elle-même ne l'est pas.
En fin de compte, ce n'est pas l'existence de getters qui a tort. Ils sont bien meilleurs que les domaines publics. Ce qui est mauvais, c'est quand ils sont utilisés pour prétendre que vous êtes orienté objet alors que vous ne l'êtes pas. Les Getters sont bons. Être orienté objet est bon. Les getters ne sont pas orientés objet. Utilisez des getters pour tailler un endroit sûr pour être orienté objet.