Menu
Coddy logo textTech

Implementazione dell'occultamento dei dati

Fa parte della sezione Programmazione orientata agli oggetti del percorso C# di Coddy. Lezione 33 di 70.

La protezione dei dati va oltre il semplice uso di campi private. Si tratta di progettare la tua classe in modo che i dettagli interni dell’implementazione siano completamente invisibili al codice esterno, esponendo solo ciò che è necessario tramite un’interfaccia pubblica chiara.

Considera una classe che tiene traccia della password di un utente. Non vuoi che nessuno possa accedere alla password in chiaro, nemmeno per leggerla:

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();
    }
}

Nota che non c’è modo di recuperare la password o persino l’hash. Il codice esterno può solo impostare una password o verificarne una: il meccanismo di archiviazione interno è completamente nascosto. Anche il metodo HashPassword è privato perché è un dettaglio di implementazione che potrebbe cambiare senza influire sul modo in cui viene usata la classe.

Questo approccio protegge la tua classe dall'uso improprio e ti dà la libertà di modificare gli elementi interni in seguito. Se decidi di usare un algoritmo di hashing diverso, nessun codice esterno si interrompe, perché nulla dipendeva dal modo in cui era archiviata la password.

challenge icon

Sfida

Facile

Costruiamo un sistema di portafoglio sicuro che dimostri il vero occultamento dei dati. Creerai un portafoglio digitale in cui il saldo è completamente protetto dall'accesso diretto: il codice esterno può solo depositare, prelevare e verificare se le transazioni sono possibili, ma non può mai vedere o manipolare direttamente il saldo effettivo.

Organizzerai il codice in due file:

  • Wallet.cs: crea una classe Wallet nello spazio dei nomi Finance che mantiene il saldo completamente nascosto. Il portafoglio deve avere:
    • Un campo privato per memorizzare il saldo (decimal)
    • Un metodo privato FormatBalance() che restituisce il saldo formattato come stringa di valuta, ad esempio "$123.45" - è un helper interno che non dovrebbe essere esposto
    • Un metodo pubblico Deposit(decimal amount) che aggiunge al saldo solo se l'importo è positivo e restituisce true se l'operazione riesce, false altrimenti
    • Un metodo pubblico Withdraw(decimal amount) che sottrae dal saldo solo se l'importo è positivo e non supera il saldo corrente, restituendo true se l'operazione riesce, false altrimenti
    • Un metodo pubblico CanAfford(decimal amount) che restituisce true se il saldo è maggiore o uguale all'importo, false altrimenti
    • Un metodo pubblico GetStatement() che usa internamente il metodo privato FormatBalance() e restituisce "Current balance: {formatted balance}"
    Nota che non c'è modo di leggere o impostare direttamente il saldo: puoi interagire con esso solo tramite metodi controllati!
  • Program.cs: nel tuo file principale, crea un Wallet ed esegui una serie di transazioni usando i valori di input. Mostra come il portafoglio protegge il proprio stato interno, offrendo comunque funzionalità utili tramite la sua interfaccia pubblica.

Riceverai tre input:

  • Importo del deposito iniziale (decimal)
  • Importo del prelievo da tentare (decimal)
  • Importo per cui verificare la disponibilità (decimal)

Stampa l'output in questo formato:

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

Per esempio, se gli input sono 100.50, 30.25 e 80.00, l'output dovrebbe essere:

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

L'intuizione chiave è che il codice esterno non accede mai direttamente al campo del saldo. Anche la stringa del saldo formattato viene restituita tramite un metodo pubblico che usa internamente un helper privato. Questo è l'occultamento dei dati: i dettagli di implementazione sono completamente invisibili e puoi modificare il modo in cui il saldo viene memorizzato o formattato senza compromettere il codice che usa il tuo portafoglio!

Provalo tu

using System;
using Finance;

class Program
{
    public static void Main(string[] args)
    {
        // Leggi i valori di input
        decimal depositAmount = Convert.ToDecimal(Console.ReadLine());
        decimal withdrawAmount = Convert.ToDecimal(Console.ReadLine());
        decimal checkAmount = Convert.ToDecimal(Console.ReadLine());

        // TODO: Crea un'istanza di Wallet
        
        // TODO: Effettua un deposito e stampa il risultato nel formato: "Deposit {amount}: {True/False}"
        
        // TODO: Stampa l'estratto conto usando GetStatement()
        
        // TODO: Effettua un prelievo e stampa il risultato nel formato: "Withdraw {amount}: {True/False}"
        
        // TODO: Stampa l'estratto conto usando GetStatement()
        
        // TODO: Verifica se l'importo è disponibile e stampa il risultato nel formato: "Can afford {amount}: {True/False}"
    }
}
quiz iconMettiti alla prova

Questa lezione include un breve quiz. Inizia la lezione per rispondere e tenere traccia dei tuoi progressi.

Tutte le lezioni di Programmazione orientata agli oggetti

Esercitati da solo: Compilatore C# online