Entwicklung von Software nach dem Bausteinprinzip

Zielsetzung

Wenn man die richtigen Bausteine zur Verfügung hat, dann ist es meist recht einfach, das gewünschte System zu entwickeln.

Bausteine
Quelle: Wikimedia Commons

Das gilt nicht nur für Systeme im Alltag, diese Aussage trifft auch auf die Entwicklung von Software zu. Wir haben in den vorangegangenen Abschnitten Programme zu Kartenspielen entwickelt. Dabei war es äußerst hilfreich, auf Klassen als fertige Softwarebausteine zurückgreifen zu können.

Wir schauen uns hier noch diese Vorgehensweise genauer an. Insbesondere geht es um die Frage, wie eine Klasse aufbereitet werden sollte, damit sie von einem Benutzer direkt als Baustein verwendet werden kann.

Verwendung von Klassen

Betrachte das folgende Testprogramm zur Simulation des 17-und-4-Spiels.

from kartenspiel import Kartenstapel, Kartenhaufen
# Testprogramm
kartenstapel = Kartenstapel()
kartenstapel.mischen()
meinKartenhaufen = Kartenhaufen()
while meinKartenhaufen.getWert() < 18:
    karte = kartenstapel.karteZiehen()
    meinKartenhaufen.hinzufuegen(karte)
print(meinKartenhaufen.getKartenListe())
print(meinKartenhaufen.getWert())

Damit dieses Programm funktioniert, benötigt man Implementierungen der Klassen Kartenstapel und Kartenhaufen. Du findest eine Implementierung dieser Klassen in der Datei kartenspiel.py.

Aufgabe 1

(a) Was muss man als Benutzer alles über die Klassen Kartenstapel und Kartenhaufen wissen, um ein Programm wie das oben gezeigte schreiben zu können?

(b) Der Entwickler der Klassen Kartenstapel und Kartenhaufen veröffentlicht die folgenden Klassendiagramme:

Klassendiagramm KartenstapelKlassendiagramm Kartenhaufen

Welche Informationen über die Klassen Kartenstapel und Kartenhaufen findet man hier? Welche zur Nutzung der Klasse benötigten Informationen sind hier nicht dokumentiert?

(c) Der Entwickler der Klasse Kartenstapel hat die Implementierung der Methoden mit Kommentaren versehen.

Welche Informationen kann ein Nutzer hieraus entnehmen? Muss ein Nutzer auch die Details der Implementierung verstehen, um die Klasse nutzen zu können?

#-----------------------------------------------------------
# Kartenstapel
#-----------------------------------------------------------

from random import randint

class Kartenstapel(object):

    __slots__ = ('kartenListe')
    
    def __init__(self):

        """
        Die Methode __init__ erzeugt ein Kartenstapel-Objekt.
        Die 32 Karten werden hier in einer festen Reihenfolge
        in kodierter Form vorgegeben:
        'X-A' (Kreuz Ass), ..., 'K-7' (Karo 7)
        """

        self.kartenListe = [
            'X-A', 'X-K', 'X-D', 'X-B', 'X-10', 'X-9', 'X-8', 'X-7',
            'P-A', 'P-K', 'P-D', 'P-B', 'P-10', 'P-9', 'P-8', 'P-7',
            'H-A', 'H-K', 'H-D', 'H-B', 'H-10', 'H-9', 'H-8', 'H-7',
            'K-A', 'K-K', 'K-D', 'K-B', 'K-10', 'K-9', 'K-8', 'K-7'
            ]

    def mischen(self):

        """
        Die aktuell im Kartenstapel vorliegenden Karten werden neu angeordnet.
        Hierzu wird eine zufällig gewählte neue Reihenfolge bestimmt.
        """

        neueListe = []
        aktuelleAnzahl = len(self.kartenListe)
        while aktuelleAnzahl > 0:
            i = randint(0, aktuelleAnzahl-1)
            neueListe = neueListe + [self.kartenListe[i]]
            del self.kartenListe[i]
            aktuelleAnzahl = len(self.kartenListe)
        self.kartenListe = neueListe

    def istLeer(self):

        """
        Die Methode liefert als Ergebnis True / False,
        falls der Kartenstapel leer / nicht leer ist.
        """

        if len(self.kartenListe) > 0:
            ergebnis = False
        else:
            ergebnis = True
        return ergebnis

    def karteZiehen(self):

        """
        Die oberste (erste) Karte des Kartenstapel wird aus
        dem Kartenstapel entfernt und als Ergebnis zurückgegeben
        Ist der Kartenstapel leer, wird keine Karte gezogen
        und der Wert None zurückgegeben.
        """

        if len(self.kartenListe) > 0:
            gezogeneKarte = self.kartenListe[0]
            self.kartenListe = self.kartenListe[1:]
        else:
            gezogeneKarte = None
        return gezogeneKarte

    def getKartenListe(self):

        """
        Die noch auf den Kartenstapel befindlichen Karten werden
        als Liste von Karten zurückgegeben.
        """

        return self.kartenListe

    def setKartenListe(self, vorgegebeneKarten):

        """
        Die übergebene Kartenliste wird übernommen und bildet
        den neuen Vorrat an Karten im Kartenstapel.
        """

        self.kartenListe = vorgegebeneKarten

(d) Führe die Datei kartenspiel.py einmal aus, damit Python die Klassendeklaration übernimmt. Führe anschließend den help-Befehl wie folgt aus:

>>> help(Kartenstapel)
Help on class Kartenstapel in module __main__:

class Kartenstapel(builtins.object)
 |  Methods defined here:
 |  
 |  __init__(self)
 |      Die Methode __init__ erzeugt ein Kartenstapel-Objekt.
 |      Die 32 Karten werden hier in einer festen Reihenfolge
 |      in kodierter Form vorgegeben:
 |      'X-A' (Kreuz Ass), ..., 'K-7' (Karo 7)
 |  
 |  getKartenListe(self)
 |      Die noch auf den Kartenstapel befindlichen Karten werden
 |      als Liste von Karten zurückgegeben.
 |  
 |  istLeer(self)
 |      Die Methode liefert als Ergebnis True / False,
 |      falls der Kartenstapel leer / nicht leer ist.
 |  
 |  karteZiehen(self)
 |      Die oberste (erste) Karte des Kartenstapel wird aus
 |      dem Kartenstapel entfernt und als Ergebnis zurückgegeben
 |      Ist der Kartenstapel leer, wird keine Karte gezogen
 |      und der Wert None zurückgegeben.
 |  
 |  mischen(self)
 |      Die aktuell im Kartenstapel vorliegenden Karten werden neu angeordnet.
 |      Hierzu wird eine zufällig gewählte neue Reihenfolge bestimmt.
 |  
 |  setKartenListe(self, vorgegebeneKarten)
 |      Die übergebene Kartenliste wird übernommen und bildet
 |      den neuen Vorrat an Karten im Kartenstapel.
 |  
 |  ----------------------------------------------------------------------
 |  Data descriptors defined here:
 |  
 |  kartenListe

Teste entsprechend, welche Informationen zur Klasse Kartenhaufen angezeigt werden.

Warum sollte man die (öffentlichen) Methoden einer Klasse möglichst gut dokumentieren?

(e) Ergänze möglichst informative Kommentare in der Implementierung der Klasse Kartenhaufen.

Quellen

X

Fehler melden

X

Suche