Encapsulation des données
|
|
Le résumé introductif est absent ou ne respecte pas les recommandations.
|
|
|
L'article doit être débarrassé d'une partie de son jargon.
Sa qualité peut être largement améliorée en utilisant un vocabulaire plus directement compréhensible. Discutez des points à améliorer en page de discussion.
|
L'encapsulation des données (ou encapsulage des données) est une règle de microarchitecture (architecture détaillée) consistant à cacher les données d’une classe ou d’un module aux autres classes ou modules, c'est-à-dire, empêcher l'accès aux données par un autre moyen que des méthodes (fonctions membres). Par conséquent, l’interface d’une classe ou d’un module obéissant à ce principe n’expose jamais ces membres de données comme des variables, tableaux ou structures mais seulement des méthodes (fonctions membres).
Sommaire |
Implémentation [modifier]
Tous les langages de programmation orientée objet comme Java ou C++ offrent des limitateurs d’accès (niveaux de visibilité) permettant d’implémenter aisément le principe d’encapsulation des données. Les limitateurs traditionnels sont :
- publique : les méthodes (fonctions membres) de toutes les autres classes ou modules peuvent accéder aux données possédant le niveau de visibilité publique. Il s'agit du plus bas niveau de protection des données.
- protégée : l'accès aux données protégées est réservé aux méthodes (fonctions membres) des classes héritières. Il s'agit d’un niveau intermédiaire de protection des données.
- privée : l'accès aux données privées est limité aux méthodes (fonctions membres) de la classe propriétaire. Il s'agit du niveau le plus élevé de protection des données.
Malheureusement, aucun langage de programmation orientée objet oblige le programmeur à protéger les données membres, autrement dit, il est toujours possible de les déclarer publiques. Il s’agit d’un anti-patron de conception que tout bon programmeur évite à tout prix et ce pour plusieurs raisons.
Motivations [modifier]
- L'encapsulation permet de changer les structures de données d’un module ou d’une classe sans modifier l’interface de celle-ci et donc sans modifier les classes et modules qui l’utilisent. Cette situation arrive fréquemment lorsque l’on veut augmenter l’efficacité (rapidité de traitement) d’une classe ou d’un module, il faut souvent modifier les structures de données en conséquence.
- L'encapsulation permet d’ajouter aisément des règles de validation et des contraintes d’intégrité comme, par exemple, limiter le domaine des valeurs qu’une variable peut prendre (validité) ou vérifier que cette valeur n’entre pas en conflit avec les valeurs d’autres variables (intégrité).
- Plus généralement, l'encapsulation permet d’informer la classe qu’un changement à ses données est sur le point de survenir. Si cette information devient éventuellement cruciale, le programmeur n’ayant pas encapsulé les données se trouvera devant une impasse.
- L'encapsulation évite l’antipattern plat de spaghetti qui ne permet pas de déterminer le qui, le quoi et le comment d’une modification de données. En effet, l'application systématique de l'encapsulation impose un couplage faible et empêche donc le couplage fort, par espace commun ou par contenu, responsable du plat de spaghetti.
- Finalement, l'encapsulation permet d’offrir une interface orientée services et responsabilités, c’est-à-dire, d’offrir aux utilisateurs (programmeurs, abstractionnistes et architectes) de la classe ou du module une interface indiquant clairement quels services sont offerts et quelles sont les responsabilités de cette classe ou module.
Accesseur et mutateur [modifier]
Une erreur commune est de confondre le principe d'encapsulation et les accesseurs et mutateurs (getter / setter). Alors que le premier implique une notion de boîte noire (l'utilisateur de la "boîte" n'a pas conscience des traitements internes de cette "boîte"), les accesseurs et mutateurs explicite ce traitement, de par l'utilisation d'une fonction (getMember(), setMember(..) ..) En outre, pratiquer les accesseurs / mutateurs dégradent considérablement la visibilité, la simplicité du code. Le code source qui en résulte est généralement moins clair à analyser.
Cette confusion est généralisée de part la démocratisation du langage java, lequel ne permet pas de pratiquer le principe d'encapsulation. L'utilisation des accesseurs et mutateurs devient donc, pour ce langage, un moindre mal, un palliatif.
La bonne implémentation du principe d'encapsulation est l'utilisation des surcharges d'opérateurs. Le code est éxécuté sans que l'appelant ne soit mis au courant.
Exemple en php:
class sample { private $member; // Mutateur implicite public function __set($name, $value){ echo "Définition de '$name' à la valeur '$value'\n"; if($name == "member"){ //Faire des tests, lever une exception, stocker la variable $this->member = $value; } else { //Générique : pour les autres variables $this->data[$name] = $value; } } // Accesseur implicite public function __get($name){ //Appliquer du traitement en fonction de $name echo "Récupération de '$name'\n"; if (array_key_exists($name, $this->data)) { return $this->data[$name]; } } } $obj = new Sample; $obj->member = "test"; //Applique le code ci-dessus echo $obj->member; //Idem
Exemple en Python :
class sample: def __init__(self): self.__member = None def getMember(self): print("Recuperation de self.__member") return(self.__member) def setMember(self, value): print("Ecriture de '%s' dans self.__member" % (value)) self.__member = value member = property(getMember, setMember) t = sample() t.member = "une valeur" print(t.member)
Voir aussi [modifier]
- Le principe de masquage de l'information.
- La métrique de cohésion.
- La métrique de couplage.
- La métrique d'indépendance fonctionnelle.
Notes et références [modifier]
Pressman R. S., Software Engineering: A Practitioner's Approach, Third Edition. McGraw-Hill. Chapitre 10, 1992.