Menu
Coddy logo textTech

Informationsverbergung

Teil des Abschnitts Objektorientierte Programmierung der Dart-Journey von Coddy. Lektion 34 von 110.

Informationsverbergung ist das Prinzip hinter der Kapselung – die Idee, dass eine Klasse ihre interne Funktionsweise verbergen und nur das Notwendige offenlegen sollte. Du hast die Mechanismen (private Felder, Getter, Setter) kennengelernt, aber das eigentliche Ziel besteht darin, Klassen zu entwerfen, die einfach zu verwenden und schwer falsch zu verwenden sind.

Betrachten Sie eine Klasse, die das Passwort eines Benutzers verwaltet. Die interne Speicherung und die Hashing-Logik sollten vollständig verborgen sein:

class UserAccount {
  String _username;
  String _passwordHash;
  
  UserAccount(this._username, String password) 
      : _passwordHash = _hashPassword(password);
  
  static String _hashPassword(String password) {
    return 'hashed_$password';  // Vereinfachtes Beispiel
  }
  
  bool verifyPassword(String password) {
    return _passwordHash == _hashPassword(password);
  }
  
  String get username => _username;
}

Externer Code sieht niemals den Passwort-Hash oder weiß, wie er gespeichert wird. Sie rufen einfach verifyPassword() auf. Diese Trennung bedeutet, dass Sie den Hashing-Algorithmus vollständig ändern könnten, ohne den Code zu beeinflussen, der diese Klasse verwendet.

Die entscheidende Erkenntnis besteht darin, Ihre Klasse von außen nach innen zu betrachten.

Frage dich: „Was benötigt jemand, der diese Klasse verwendet, tatsächlich?“ Mache nur das zugänglich und halte alles andere privat. Dadurch entsteht eine klare Grenze zwischen dem, was deine Klasse tut (ihrer öffentlichen Schnittstelle), und der Art und Weise, wie sie es tut (ihrer privaten Implementierung).

challenge icon

Aufgabe

Einfach

Lass uns ein sicheres Wallet-System entwickeln, das Informationsverbergung in der Praxis demonstriert. Du erstellst ein digitales Wallet, das den Kontostand und den Transaktionsverlauf eines Benutzers verwaltet und alle sensiblen internen Details vollständig vor externem Code verbirgt.

Du organisierst deinen Code in zwei Dateien:

  • wallet.dart: Erstelle eine Wallet-Klasse, die Geld sicher verwaltet. Das Wallet sollte den Namen des Besitzers öffentlich speichern, aber alles andere hinter einer übersichtlichen öffentlichen Schnittstelle verbergen:
    • Der interne Kontostand und das Transaktionsprotokoll sollten privat sein – externer Code sollte niemals sehen, wie du Geld speicherst oder nachverfolgst
    • Eine private Methode sollte die interne Aufzeichnung von Transaktionen übernehmen (und Einträge wie "Deposit: $50.0" oder "Withdrawal: $30.0" speichern)
    • Stelle eine öffentliche Methode deposit(double amount) bereit, die Geld hinzufügt (nur wenn der Betrag positiv ist) und die Transaktion intern aufzeichnet
    • Stelle eine öffentliche Methode withdraw(double amount) bereit, die Geld nur dann abzieht, wenn ausreichend Geld vorhanden und der Betrag positiv ist, und die Transaktion intern aufzeichnet. Gib true zurück, wenn der Vorgang erfolgreich war, andernfalls false
    • Stelle einen öffentlichen Getter balance bereit, der den aktuellen Kontostand zurückgibt (schreibgeschützter Zugriff)
    • Stelle eine öffentliche Methode getTransactionCount() bereit, die zurückgibt, wie viele Transaktionen aufgezeichnet wurden (ohne die tatsächliche Transaktionsliste offenzulegen)
    • Stelle eine öffentliche Methode getLastTransaction() bereit, die die letzte Transaktion als Zeichenfolge zurückgibt oder "No transactions", wenn keine vorhanden sind
    • Füge eine Methode printSummary() hinzu, die den Status des Wallets anzeigt
  • main.dart: Importiere dein Wallet und demonstriere, wie Informationsverbergung eine übersichtliche, sichere Schnittstelle schafft:
    • Erstelle ein Wallet für den Besitzer "Sarah"
    • Zahle 100.0 ein
    • Zahle 50.0 ein
    • Versuche, 200.0 abzuheben, und gib abhängig vom Ergebnis "Withdrawal of 200.0: [success/failed]" aus
    • Hebe 30.0 ab und gib "Withdrawal of 30.0: [success/failed]" aus
    • Rufe printSummary() auf
    • Gib "Transaction count: [count]" aus
    • Gib "Last transaction: [transaction]" aus

Die Methode printSummary() sollte Folgendes ausgeben:

=== Wallet Summary ===
Owner: [ownerName]
Balance: $[balance]

Beachte, wie externer Code über klare, zielgerichtete Methoden mit dem Wallet interagieren kann, ohne jemals zu wissen, wie der Kontostand gespeichert oder wie Transaktionen intern nachverfolgt werden. Die Implementierungsdetails sind vollständig verborgen – du könntest ändern, wie Transaktionen gespeichert werden, ohne irgendeinen Code zu beeinflussen, der das Wallet verwendet.

Erwartete Ausgabe:

Withdrawal of 200.0: failed
Withdrawal of 30.0: success
=== Wallet Summary ===
Owner: Sarah
Balance: $120.0
Transaction count: 3
Last transaction: Withdrawal: $30.0

Probier es selbst

import 'wallet.dart';

void main() {
  // TODO: Erstelle eine Wallet für die Besitzerin "Sarah"
  
  // TODO: Zahle 100.0 ein
  
  // TODO: Zahle 50.0 ein
  
  // TODO: Versuche 200.0 abzuheben und gib das Ergebnis aus
  // Format: "Withdrawal of 200.0: [success/failed]"
  
  // TODO: Hebe 30.0 ab und gib das Ergebnis aus
  // Format: "Withdrawal of 30.0: [success/failed]"
  
  // TODO: Rufe printSummary() auf
  
  // TODO: Gib die Anzahl der Transaktionen aus
  // Format: "Transaction count: [count]"
  
  // TODO: Gib die letzte Transaktion aus
  // Format: "Last transaction: [transaction]"
}
quiz iconTeste dich selbst

Diese Lektion enthält ein kurzes Quiz. Starte die Lektion, um es zu beantworten und deinen Fortschritt zu speichern.

Alle Lektionen in Objektorientierte Programmierung

Übe selbstständig: Online-Dart-Compiler