Checkmark on Circle.png

Datenkapselung

Aus KGS-Wiki
Version vom 29. September 2023, 10:04 Uhr von Sn (Diskussion | Beiträge) (Seite angelegt)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)

Datenkapselung ist ein Konzept aus der objektorientierten Programmierung. Die Idee ist, dass Objekte ihre Attribute nicht öffentlich zur Verfügung stellen sollten. Stattdessen stellen die Objekte Schnittstellen zur Verfügung, um den Zugriff auf diese Attribute kontrollieren zu können.

Damit behalten Objekte selbst die Kontrolle über ihre Daten und definieren selbst, wer welchen Zugriff darauf haben kann. Damit kann z.B. eine Autorisierung eingefordert werden oder verhindert werden, dass zwei parallel laufende Threads gleichzeitig ein Objekt verändern (Race condition). Auch unsinnige Eingabewerte können so verhindert werden.

Der Zugriff auf diese Attribute erfolgt über Methoden, deren Namen typischerweise mit get oder set beginnen und die darum Getter und Setter genannt werden. Dies ist aber keinesfalls vorgeschrieben, der Zugriff kann auch anderweitig eingeschränkt werden.

Beispiele

Brüche in Python

Das folgende Beispiel zeigt eine Python-Klasse für Brüche.

class Fraction:

	def __init__(self, numerator, denominator):
        if type(numerator) != int or type(denominator) != int:
            raise Exception('Zähler und Nenner müssen ganze Zahlen sein!')
        if denominator == 0:
            raise Exception('Der Nenner darf nicht 0 sein!')
        self.__numerator = numerator
        self.__denominator = denominator

	def get_numerator(self):
		return self.__numerator

	def set_numerator(self, numerator):
        if type(numerator) != int:
            raise Exception('Der Zähler muss eine ganze Zahl sein!')
        self.__numerator = numerator

	def get_denominator(self):
		return self.__denominator

	def set_denominator(self, denominator):
        if type(denominator) != int:
            raise Exception('Der Nenner muss eine ganze Zahl sein!')
        if denominator == 0:
            raise Exception('Der Nenner darf nicht 0 sein!')
        self.__denominator = denominator

Folgendermaßen wird die Datenkapselung in dieser Klasse umgesetzt:

  • Diese Klasse hat zwei Attribute: __numerator und __denominator (Z. 8, 9).
  • Durch die führenden __ wird die Sichtbarkeit der Variablen auf private gesetzt.
  • Der Zugriff ist nur über die Methoden get_numerator (Z. 11), set_numerator (Z. 14), get_denominator (Z. 19) und set_denominator (Z. 22) möglich.
  • Die Setter überprüfen dabei, ob die übergebenen Parameter auch wirklich ganze Zahlen sind und erzeugen eine Exception, falls dies nicht der Fall ist (Z. 16, 24).
  • set_denominator stellt außerdem sicher, dass der Nenner nicht auf 0 gesetzt wird, da dies mathematisch nicht möglich ist (Z. 26).

Konten in Java

Das folgende Beispiel zeigt eine Java-Klasse für Bankkonten mit einem angedeuteten Sicherheitsmechanismus in Form einer PIN.

public class BankAccount {

    private double amount;
    private int pin;

    public BankAccount(int pin) {
        this.amount = 0;
        this.pin = pin;
    }

    public double getAmount(int pin) throws WrongPinException{
        if (this.pin != pin) {
            throw new WrongPinException();
        }
        return amount;
    }

    public void deposit(double amountToDeposit) {
        this.amount = this.amount + amountToDeposit;
    }

    public void withdraw(int pin, double amountToWithdraw) throws YouAreBrokeException, WrongPinException {
        if (this.pin != pin) {
            throw new WrongPinException();
        }
        if (this.amount < amountToWithdraw) {
            throw new YouAreBrokeException();
        }
        this.amount = this.amount - amountToWithdraw;
    }
}
  • In Java wird die Sichtbarkeit der Attribute mit dem Schlüsselwort private eingeschränkt (Z. 3, 4).
  • Hier gibt es statt eines Setters zwei Methoden deposit (Z. 18) und withdraw (Z. 22), mit denen der Kontostand um eine gewisse Summe verändert werden kann.
  • Die Getter und Setter prüfen hier als primitive Sicherheitskontrolle, ob eine übergebene pin mit der gespeicherten pin übereinstimmt (Z. 12, 23), und zusätzlich beim Abheben, ob genug Geld auf dem Konto vorhanden ist (Z. 26). Ansonsten werden auch hier Exceptions produziert (Z. 13, 24, 27).