Menu
Coddy logo textTech

Implémentation du masquage de données

Fait partie de la section Programmation Orientée Objet du Journey C# de Coddy — leçon 33 sur 70.

La dissimulation des données va au-delà de la simple utilisation de champs private. Il s'agit de concevoir votre classe de manière à ce que les détails d'implémentation interne soient complètement invisibles pour le code extérieur, en n'exposant que ce qui est nécessaire via une interface publique propre.

Considérez une classe qui suit le mot de passe d'un utilisateur. Vous ne voulez pas que quiconque accède au mot de passe brut - pas même pour le lire :

public class UserAccount
{
    private string passwordHash;
    
    public void SetPassword(string password)
    {
        passwordHash = HashPassword(password);
    }
    
    public bool VerifyPassword(string password)
    {
        return HashPassword(password) == passwordHash;
    }
    
    private string HashPassword(string password)
    {
        return password.GetHashCode().ToString();
    }
}

Remarquez qu'il n'y a aucun moyen de récupérer le mot de passe ou même le hachage. Le code externe peut seulement définir un mot de passe ou en vérifier un - le mécanisme de stockage interne est complètement caché. La méthode HashPassword est également privée car il s'agit d'un détail d'implémentation qui pourrait changer sans affecter la façon dont la classe est utilisée.

Cette approche protège votre classe contre une mauvaise utilisation et vous donne la liberté de modifier les éléments internes plus tard. Si vous décidez d'utiliser un algorithme de hachage différent, aucun code externe ne sera interrompu car rien ne dépendait de la manière dont le mot de passe était stocké.

challenge icon

Défi

Facile

Construisons un système de portefeuille sécurisé qui démontre une véritable dissimulation de données. Vous allez créer un portefeuille numérique où le solde est complètement protégé contre tout accès direct - le code externe peut uniquement déposer, retirer et vérifier si les transactions sont possibles, mais ne peut jamais voir ou manipuler le solde réel directement.

Vous organiserez votre code sur deux fichiers :

  • Wallet.cs : Créez une classe Wallet dans l'espace de noms Finance qui garde son solde complètement caché. Le portefeuille doit avoir :
    • Un champ privé pour stocker le solde (decimal)
    • Une méthode privée FormatBalance() qui renvoie le solde formaté sous forme de chaîne monétaire comme "$123.45" - il s'agit d'une aide interne qui ne doit pas être exposée
    • Une méthode publique Deposit(decimal amount) qui ajoute au solde uniquement si le montant est positif, renvoyant true en cas de succès, false sinon
    • Une méthode publique Withdraw(decimal amount) qui soustrait du solde uniquement si le montant est positif et ne dépasse pas le solde actuel, renvoyant true en cas de succès, false sinon
    • Une méthode publique CanAfford(decimal amount) qui renvoie true si le solde est supérieur ou égal au montant, false sinon
    • Une méthode publique GetStatement() qui utilise la méthode privée FormatBalance() en interne et renvoie "Current balance: {formatted balance}"
    Remarquez qu'il n'y a aucun moyen de lire ou de définir directement le solde - vous ne pouvez interagir avec lui que par le biais de méthodes contrôlées !
  • Program.cs : Dans votre fichier principal, créez un Wallet et effectuez une série de transactions en utilisant les valeurs d'entrée. Montrez comment le portefeuille protège son état interne tout en offrant des fonctionnalités utiles via son interface publique.

Vous recevrez trois entrées :

  • Montant du dépôt initial (decimal)
  • Montant du retrait à tenter (decimal)
  • Montant pour lequel vérifier la capacité de paiement (decimal)

Affichez la sortie dans ce format :

Deposit {amount}: {True/False}
{GetStatement() result}
Withdraw {amount}: {True/False}
{GetStatement() result}
Can afford {amount}: {True/False}

Par exemple, si les entrées sont 100.50, 30.25, et 80.00, la sortie devrait être :

Deposit 100.50: True
Current balance: $100.50
Withdraw 30.25: True
Current balance: $70.25
Can afford 80.00: False

L'idée clé ici est que le code externe ne touche jamais directement le champ du solde. Même la chaîne de solde formatée provient d'une méthode publique qui utilise en interne une aide privée. C'est la dissimulation de données - les détails d'implémentation sont complètement invisibles, et vous êtes libre de modifier la façon dont le solde est stocké ou formaté sans casser le code qui utilise votre portefeuille !

Aide-mémoire

La dissimulation de données consiste à concevoir des classes de manière à ce que les détails d'implémentation interne soient complètement invisibles pour le code externe, en n'exposant que le nécessaire via une interface publique propre.

Utilisez des champs private pour stocker des données sensibles et fournissez un accès contrôlé via des méthodes public :

public class UserAccount
{
    private string passwordHash;
    
    public void SetPassword(string password)
    {
        passwordHash = HashPassword(password);
    }
    
    public bool VerifyPassword(string password)
    {
        return HashPassword(password) == passwordHash;
    }
    
    private string HashPassword(string password)
    {
        return password.GetHashCode().ToString();
    }
}

Principes clés :

  • Aucun accès direct aux données internes (pas de getters pour les champs sensibles)
  • Méthodes d'aide privées pour les détails d'implémentation
  • Les méthodes publiques fournissent uniquement des opérations contrôlées
  • Le mécanisme de stockage interne est complètement caché

Cela protège la classe contre une mauvaise utilisation et permet de modifier l'implémentation interne sans casser le code externe.

Essayez vous-même

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // Lire les valeurs d'entrée
        decimal depositAmount = Convert.ToDecimal(Console.ReadLine());
        decimal withdrawAmount = Convert.ToDecimal(Console.ReadLine());
        decimal checkAmount = Convert.ToDecimal(Console.ReadLine());

        // TODO: Créer une instance de Wallet
        
        // TODO: Effectuer un dépôt et afficher le résultat au format : "Deposit {amount}: {True/False}"
        
        // TODO: Afficher le relevé en utilisant GetStatement()
        
        // TODO: Effectuer un retrait et afficher le résultat au format : "Withdraw {amount}: {True/False}"
        
        // TODO: Afficher le relevé en utilisant GetStatement()
        
        // TODO: Vérifier la capacité de paiement et afficher le résultat au format : "Can afford {amount}: {True/False}"
    }
}
quiz iconTestez-vous

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