Envoyé par
Pyramidev
Par exemple, dans une entreprise, admettons que plusieurs programmes utilisent une bibliothèque commune interne à cette entreprise. Cette bibliothèque contient une classe de log LogueurCommun qui a une variable membre privée de type LegacyLogger fournie par une bibliothèque externe. Un jour, on veut se débarrasser de LegacyLogger et on veut la remplacer par NewCoolLogger.
Si LogueurCommun a la très mauvaise idée d'avoir une fonction publique getLegacyLogger alors, le jour où on voudra faire le changement, il faudra consulter les développeurs responsables des différents logiciels pour demander : « Salut, est-ce que quelqu'un ici appelle cette abominable fonction getLegacyLogger ? Si oui, quelles fonctionnalités de LegacyLogger utilisez-vous ? »
Si LogueurCommun a plein de méthodes publiques dont certaines qui seraient difficiles à réimplémenter avec NewCoolLogger, alors il faut voir aussi les développeurs pour savoir si on peut simplifier l'interface.
Par contre, si les méthodes publiques de LogueurCommun se restreignent au nécessaire et qu'il est facile de les réimplémenter après avoir remplacé LegacyLogger par NewCoolLogger, alors on peut mettre à jour l'implémentation de LogueurCommun sans faire de changements non rétrocompatibles dans l'interface et tout le monde est content.
De manière générale, plus on donne d'informations sur ce qu'il y a sous le capot, moins on a d'encapsulation. Or, les accesseurs (alias getters) et les mutateurs (alias setters) donnent beaucoup d'informations sur ce qu'il y a sous le capot.
Bien sûr, il y a des cas où les accesseurs sont justifiés. Par exemple, si on crée une classe qui représente un point du plan, alors il est généralement normal d'avoir un accesseur qui retourne l'abscisse et un autre qui retourne l'ordonnée.