Validation dans les setters
Fait partie de la section Programmation Orientée Objet du Journey C de Coddy. Leçon 20 sur 61.
Dans la leçon précédente, nous avons créé des setters basiques qui attribuent simplement des valeurs. Mais cela ne tient pas compte d’un avantage essentiel de l’encapsulation : la possibilité de protéger vos données en ajoutant une logique de validation.
Considérez un Counter qui ne devrait jamais devenir négatif. Sans encapsulation, n’importe qui pourrait écrire c->value = -50 et corrompre l’état. Avec un setter, vous contrôlez les valeurs autorisées :
// counter.c
void counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return; // Rejeter silencieusement les entrées invalides
}
c->value = new_value;
}Désormais, les valeurs négatives sont simplement ignorées.
Vous pouvez également choisir de renvoyer un code d’état pour indiquer le succès ou l’échec :
int counter_set_value(Counter *c, int new_value) {
if (new_value < 0) {
return 0; // Échec
}
c->value = new_value;
return 1; // Succès
}Ce modèle permet à l'appelant de savoir si l'opération a réussi. L'idée essentielle est que les setters ne servent pas uniquement à effectuer une affectation : ce sont des gardiens qui imposent des règles concernant l'état que votre objet peut avoir. C'est là le véritable pouvoir de l'encapsulation : votre objet préserve sa propre intégrité, quelles que soient les actions tentées par du code externe.
Défi
FacileConstruisons un module Temperature qui protège ses données grâce à une validation dans le setter. Vous créerez un outil de suivi de la température qui n'accepte que les valeurs comprises dans une plage valide : cela montre comment les setters jouent le rôle de gardiens de l'état de votre objet.
Vous allez créer trois fichiers :
temperature.h: votre interface publique utilisant le modèle du pointeur opaque. Déclarez un typeTemperatureavec uniquement une déclaration anticipée. Déclarez ces fonctions :create_temperature: prend un entier pour les degrés initiaux et renvoie un pointeur vers Temperaturefree_temperature: libère la mémoire allouéetemp_get_degrees: getter qui renvoie la valeur actuelle de la températuretemp_set_degrees: setter qui renvoie unint(1 en cas de réussite, 0 en cas d'échec)
TEMPERATURE_H.temperature.c: définissez la véritablestruct Temperatureavec un membreint degreescaché. Implémentez toutes les fonctions. L'élément essentiel est votre setter. Il ne doit accepter que les valeurs comprises entre -50 et 150 (inclus). Si la valeur est en dehors de cette plage, renvoyez 0 et laissez la température inchangée. Si elle est valide, mettez à jour la valeur et renvoyez 1.main.c: démontrez la validation en essayant de définir des températures valides et invalides, afin de montrer que les valeurs invalides sont rejetées tandis que les valeurs valides sont acceptées.
Vous recevrez trois entrées : la température initiale, une température valide à définir (dans la plage) et une température invalide à essayer (en dehors de la plage).
Dans votre fichier main, créez une Temperature avec la valeur initiale et affichez-la. Essayez ensuite de définir la température invalide, puisqu'elle doit être rejetée, affichez le résultat et montrez que la valeur reste inchangée. Enfin, définissez la température valide, affichez le résultat de la réussite et montrez la valeur mise à jour. Libérez la mémoire et confirmez le nettoyage.
Affichez la sortie dans ce format :
Initial: {degrees}
Set {invalid}: {0 or 1}
After invalid: {degrees}
Set {valid}: {0 or 1}
After valid: {degrees}
FreedPar exemple, avec les entrées 25, 100 et 200, la sortie serait :
Initial: 25
Set 200: 0
After invalid: 25
Set 100: 1
After valid: 100
FreedCela démontre la véritable puissance de l'encapsulation. Votre setter applique les règles définissant ce qui constitue une température valide, protégeant ainsi l'intégrité de l'objet quelles que soient les valeurs que le code externe tente d'assigner.
Essayez vous-même
#include <stdio.h>
#include "temperature.h"
int main() {
// Lire les entrées
int initial, valid_temp, invalid_temp;
scanf("%d", &initial);
scanf("%d", &valid_temp);
scanf("%d", &invalid_temp);
// TODO: Créer un Temperature avec la valeur initiale
// TODO: Afficher la température initiale
// Format : "Initial: {degrees}"
// TODO: Tenter de définir la température invalide
// Afficher le résultat et montrer que la valeur reste inchangée
// Format : "Set {invalid}: {0 or 1}"
// Format: "After invalid: {degrees}"
// TODO: Définir la température valide
// Afficher le résultat de succès et montrer la valeur mise à jour
// Format : "Set {valid}: {0 or 1}"
// Format : "After valid: {degrees}"
// TODO: Libérer la mémoire et afficher "Freed"
return 0;
}
Cette leçon comprend un petit quiz. Commencez la leçon pour y répondre et suivre votre progression.
Toutes les leçons de Programmation Orientée Objet
1Bases de la programmation modulaire
Fichiers d'en-têteGardes d'inclusionFichiers sourcesFonctions statiquesRécapitulatif : Calculatrice modulaire4Encapsulation
Concept des pointeurs opaquesDéfinir des structures opaquesGetters et settersValidation dans les settersRécapitulatif : La boîte secrète2Objets et méthodes
Structs comme objetsLe pointeur 'Self'Rigueur du mot-clé constPointeur vs ValeurMéthodes utilitairesRécapitulatif : Point Manager5Projet : Compte bancaire simple
Configuration du projetImplémentation du compte8Polymorphisme
Pointeurs de fonctions dans les structuresSimulation de méthodesLe concept d'interfaceImplémentation d'interfacesItération polymorphiqueRécapitulatif : Greeter11Patrons de conception en C
Patron SingletonPatron FabriquePatron ItérateurRécapitulatif : Logger Factory3Cycle de vie des objets
Pattern de constructeurPattern de destructeurInitialisation sur la pileCopie profondeRécapitulatif : String Wrapper6Héritage par composition
Imbrication de structLa règle du premier membreAccès aux membres parentsUpcastingRécapitulatif : Hiérarchie des formes9Projet : Dessinateur de formes
Aperçu du projetImplémentation du cercleImplémentation du rectangleUtilisation polymorpheConteneur de formesEntraînez-vous par vous-même : Compilateur C en ligne