« Bonjour, Amigo ! J'aimerais consacrer le cours d'aujourd'hui à l'encapsulation. Tu as déjà une idée générale de ce que c'est. »

Encapsulation - 1

Alors quels sont les avantages de l'encapsulation ? Il y en a beaucoup, mais je vais en souligner quatre qui sont, selon moi, les plus importants :

1) État interne valide.

Les programmes ont souvent plusieurs classes qui interagissent avec le même objet. En interagissant simultanément avec les données internes de l'objet, ils peuvent violer l'intégrité des données de l'objet, auquel cas l'objet cesse de fonctionner correctement.

Ainsi, l'objet doit garder la trace de chaque modification de ses données internes, ou mieux encore, être celui qui apporte ces changements.

Si nous ne voulons pas qu'une variable de classe puisse être modifiée par d'autres classes, nous la déclarons private, ce qui signifie que seules les méthodes de cette classe peuvent y accéder. Si nous voulons des variables à lecture seule pour les autres classes, nous ajoutons un getter public à ces variables.

Par exemple, nous pourrions vouloir que tout le monde puisse savoir combien d'éléments il y a dans notre collection, sans que personne ne puisse toucher à ce chiffre sans notre permission. Dans ce cas, nous déclarons une variable private int count et une méthode public getCount().

Une bonne encapsulation garantit que les autres classes ne peuvent pas accéder directement aux données internes de notre classe et, ainsi, ne peuvent pas les modifier sans que nous soyons en mesure de contrôler leurs actions. Elles doivent appeler des méthodes sur la classe qui contient les variables qui seront modifiées.

Il est préférable de supposer que les autres programmeurs utiliseront toujours tes classes de la manière qui est la plus commode pour eux, et non de la manière la plus sûre pour toi (ou ta classe). C'est une source de bogues, et un moyen de les empêcher.

2) Vérification des paramètres.

Parfois, tu dois vérifier les paramètres passés aux méthodes de ta classe. Par exemple, supposons que nous avons une classe qui représente une 'personne', et que tu peux indiquer sa date de naissance. Nous devons vérifier que toute donnée passée correspond à la logique du programme et à celle de la classe. Par exemple, il n'y a pas de 13e mois, de 30 février, etc.

« Pourquoi quelqu'un indiquerait 30 février en date de naissance ? »

« Eh bien, pour commencer, ça pourrait être le résultat d'une erreur de saisie de données. »

Ensuite, avant qu'un programme fonctionne au quart de tour, il peut avoir beaucoup de bogues. Par exemple, quelque chose comme ce qui suit pourrait se produire.

Un programmeur écrit du code qui détermine qui a un anniversaire le surlendemain. Supposons que nous sommes le 3 mars. Le programme ajoute 2 à la date actuelle et trouve tous ceux qui sont nés le 5 mars. Jusqu'ici tout va bien.

Mais quand nous arrivons au 30 mars, le programme ne trouve personne, puisqu'il n'y a pas de 32 mars. Les programmes sont beaucoup moins bogués lorsque les méthodes effectuent la vérification des paramètres. »

« Je me souviens que quand nous avons étudié ArrayList et que j'ai observé son code, il y avait des contrôles dans les méthodes get et set pour s'assurer que le paramètre d'indice était supérieur ou égal à zéro et inférieur à la longueur du tableau. Le code levait une exception si le tableau n'avait pas d'élément correspondant à l'indice.

« Oui, c'est un exemple classique de contrôle d'entrée. »

3) Moins de bogues lors de la modification du code à l'intérieur des classes.

Supposons que nous avons écrit une classe très utile dans le cadre d'un grand projet. Tout le monde l'aime tellement que les autres programmeurs ont commencé à l'utiliser dans des centaines d'endroits dans leur propre code.

Cette classe s'est avérée si utile que tu as décidé de l'améliorer. Cependant, si tu élimines une des méthodes de la classe, le code de dizaines d'autres programmeurs ne compilera plus. Ils devraient réécrire leur code de toute urgence. Et plus il y a de réécriture, plus il y a de risques de bogues. Si tu apportes sans cesse des changements cassants, le monde entier te haïra.

Mais si nous changeons les méthodes marquées comme private, nous savons que ces méthodes ne sont appelées nulle part dans le code des autres. Nous pouvons les réécrire, en modifiant le nombre et le type des paramètres, et le code qui repose dessus continuera à fonctionner. Il continuera à compiler, à tout le moins.

4) Nous définissons comment les autres objets vont interagir avec notre objet.

Nous pouvons limiter les actions qui peuvent être effectuées sur notre objet. Par exemple, nous pourrions vouloir créer une seule instance de notre classe, même si elle est créée simultanément à plusieurs endroits dans le projet. Nous pouvons y parvenir en utilisant l'encapsulation.

Encapsulation - 2

L'encapsulation nous permet d'imposer des restrictions supplémentaires qui pourraient se transformer en avantages supplémentaires. Par exemple, la classe String est implémentée en tant qu'objet immuable. Les instances de la classe String ne peuvent pas être modifiées entre leur création et leur destruction. Toutes les méthodes de la classe String (remove, substring, ...) renvoient une nouvelle chaîne et ne changent en aucun cas l'objet sur lequel elles sont appelées.

« Ben dis donc ! Alors c'est comme ça que ça marche. »

« L'encapsulation est intrigante. »

« Je suis bien de ton avis. »