Klassen- und Implementationsdiagramm: Unterschied zwischen den Versionen

Aus SibiWiki
Zur Navigation springen Zur Suche springen
Zeile 144: Zeile 144:
===Java-Quelltext:===
===Java-Quelltext:===
In den Quelltexten sind '''fett''' gedruckt die Teile, die die Beziehungen zwischen den Klassen herstellen.
In den Quelltexten sind '''fett''' gedruckt die Teile, die die Beziehungen zwischen den Klassen herstellen.
'''Klasse <code>Person</code>'''
'''Klasse <code>Person</code>'''


Zeile 158: Zeile 159:
         name = pName;
         name = pName;
         meinRoller = new Roller();
         meinRoller = new Roller();
        new GUI(meinRoller);
     }
     }
    
    
Zeile 204: Zeile 204:
</code>
</code>


'''Erklärung:'''
* Die hat-Beziehung zwischen <code>Person</code> und <code>Roller</code> wird hergestellt, indem im Konstruktor von <code>Person</code> ein <code>Roller</code> erzeugt wird.
* Dieser <code>Roller</code> wird im Attribut <code>meinRoller</code> gespeichert.
* Die <code>Person</code> kann jetzt Aufgaben an <code>meinRoller</code> '''delegieren''', indem sie geeignete Methoden von <code>meinRoller</code> aufruft.
* Die kennt-Beziehung zwischen <code>Roller</code> und <code>Tankstelle</code> wird durch die Methode <code>setTankstelle</code> hergestellt.
* Die <code>Person</code> kann jetzt das <code>tanken</code> an die <code>Tankstelle</code> '''delegieren'''.


'''Klasse Simulation'''
Diese Klasse erscheint nicht im Klassendiagramm, ist aber sinnvoll, um die Simulation überhaut starten zu können. Hier wird die Beziehung zwischen <code>Person</code> und <code>Roller</code> hergestellt.
<code>
public class Simulation
{
    private Person frank;
    private Tankstelle aral;
 
    public Simulation(){
        frank = new Person("Frank");
        aral = new Tankstelle("Aral");
        aral.setPreis(1.43);
        frank.setTankstelle(aral);
    }
}
</code>


==Beispiel für die Q1 (Listen)==
==Beispiel für die Q1 (Listen)==

Version vom 19. Mai 2017, 15:26 Uhr


  • Klassendiagramme sind wesentlicher Bestandteil der UML (=Unified Modeling Language).
  • Implementationsdiagramme gibt es nur in Nordrhein-Westfalen!

Wofür braucht man Klassendiagramme?

Klassendiagramme braucht man, um Softwaresysteme zu modellieren. Dabei wird im Klassendiagramm folgendes festgelegt:

  • Name, Attribute (mit Typ) und Methoden (mit Parameter und Rückgabetyp) jeder einzelnen Klasse.
  • Die Beziehungen zwischen den Klassen.

Nicht festgelegt wird im Klassendiagramm die konkrete Programmierung.

Sehr vereinfacht sieht der Entwicklungsprozess so aus:
Aus der Anforderungsermittlung (=einem Text, der mit dem Auftraggeber abgesprochen ist) zeichnet der Software-Architekt Klassendiagramme, die die gesamte in der Anforderungsermittlung beschriebene Funktionalität abbilden. In großen Systemen kann es mehrere hundert Klassen geben.
Anschließend können die Programmierer die im Klassendiagramm beschriebenen Klassen implementieren (z.B. in Java).

Vorgaben für das Zentralabitur

Hier die offiziellen Erläuterungen für Klassen- und Implementationsdiagramme:

Klassen- und Implementationsdiagramme (PDF)

Attribute und Methoden im Klassendiagramm

Klassendiagramm der Klasse Buch

Rechts ein einfaches Klassendiagramm für die Klasse Buch: Die Klasse Buch ist ein bloßer Informationsbehälter, d.h. die Klasse verfügt nur über get- und set-Methoden und nicht über eine eigene Logik.

Aufbau eines Klassendiagramms

Klassendiagramme haben immer drei Zeilen:

  1. Zeile: Der Name der Klasse
  2. Zeile: die Attribute der Klasse
  3. Zeile: die Methoden der Klasse
    1. Dabei wird als erstes der Konstruktor aufgeführt.

Syntax innerhalb des Klassendiagramms

Klassendiagramme haben eine eigene Syntax, die (leider!) von der Java-Syntax abweicht:

  • + bedeutet public
  • - bedeutet private
  • Attribute:
    • VOR dem Doppelpunkt: "+" bzw. "-" und der Attribut-Name
    • NACH dem Doppelpunkt: Attribut-Typ
  • Methoden:
    • erst "+" bzw. "-" (für public bzw. private)
    • Methoden-Name
    • Parameter (in Klammern!): VOR dem Doppelpunkt der Parameter-Name, NACH dem Doppelpunkt der Parameter-Typ.
    • NACH dem Doppelpunkt: Rückgabe-Typ der Methode

Java-Implementierung

Wie die einzelnen Klassen implementiert werden, das entscheidet der zuständige Programmierer; er muss sich aber genau an die Vorgaben des Klassendiagramms halten.

Das oben gegebene einfache Klassendiagramm kann z.B. wie folgt in Java implementiert werden.

public class Buch{

  //Attribute
  private String titel;
  private int regalNr;

  //Konstruktor   
  public Buch(String pTitel){
     titel = pTitel;
  }

  // get- und set-Methoden
  public int getRegalNr() {
     return regalNr;
  }

  public void setRegalNr(int pRegalNr) {
     regalNr = pRegalNr;
  }

  public String getTitel() {
     return titel;
  }
}

Beziehungen zwischen Klassen

kennt, hat, erbt von

Es gibt drei Beziehungstypen:

  • Kennt-Beziehung: Ein Objekt der Klasse A kennt ein/mehrere Objekte der Klasse B.
    Beispiel: Fahrer kennt mehrere Tankstellen.
  • Hat-Beziehung: Ein Objekt der Klasse A hat (=besitzt!) ein/mehrere Objekte der Klasse B.
    Beispiel: Fahrer hat einen Roller.
  • Vererbung: Klasse A erbt von Klasse B. Man sagt auch oft: A ist ein B
    Beispiel: Roller erbt von Fahrzeug, bzw. Roller ist ein Fahrzeug.

Wie unterscheidet man Hat- und Kennt-Beziehung?

Das hängt vom jeweiligen Szenario ab!

Die entscheidende Fragestellung ist:
Was passiert, wenn man den "Besitzer" zerstört?

  • Wenn man das andere Objekt dann auch nicht mehr braucht (d.h. ebenfalls zerstören kann), dann ist das eine "Hat-Beziehung".
  • Wenn das andere Objekt aber erhalten bleiben soll, dann ist es eine "Kennt-Beziehung".

Multiplizitäten der Hat-Beziehung und der Kennt-Beziehung

Multiplizitäten werden entweder genau oder mit einer Unter- und einer Obergrenze notiert:

  • 1: genau ein
  • 0..1: 0 oder ein
  • 2..4: mindestens 2 und höchstens 4
  • 1..*: mindestens 1 (und höchstens beliebig viele)


Beispiel

Beziehungen zwischen Roller, Fahrer und Tankstelle

Im Klassendiagramm rechts sind die Beziehungen zwischen Roller, Fahrer und Tankstelle dargestellt. (Attribute und Methoden der einzelnen Klassen sind hier nicht aufgeführt.

Erläuterung:

  • Jeder Fahrer besitzt genau einen Roller.
    Wenn man den Fahrer "zerstört", dann braucht man auch den Roller nicht mehr.
  • Jeder Fahrer kennt mindestens eine, aber beliebig viele Tankstellen.

Erstellen von Klassendiagrammen

Klassendiagramme sind vor allem Planungswerkzeuge für die Entwicklung umfangreicher Software-Systeme.

Mithilfe von Klassendiagrammen kann man festlegen, was programmiert werden muss.

Attribute, Konstruktor, Methoden

Folgende Fragestellungen helfen beim Erstellen von Klassendiagrammen:

  • Attribute: Welche Informationen müssen Objekte der Klasse speichern, damit sie im Szenario funktionieren können?
  • Parameter des Konstruktors: Welche Information muss man angeben, wenn man ein Objekt der Klasse erzeugt?
  • Methoden: Was kann man mit Objekten der Klasse tun?
    • Parameter der Methoden: Welche Information muss man der Methode mitgeben, damit sie arbeiten kann?
    • Rückgabetyp der Methoden: Gibt die Methode eine Information zurück? Welchen Datentyp hat die Rückgabe?

Beziehungen zwischen Klassen

  • Kennt bzw. hat ein Objekt der Klasse A ein (oder mehrere) Objekt(e) der Klasse B?
    • Multiplizität: Wieviele Objekte der Klasse B?
  • Welches Objekt ist ein Objekt einer anderen Klasse?

Erstellen von Implementationsdiagrammen: Top-Down-Modellierung

Für das Erstellen von Implementationsdiagrammen gibt es keine festen Regeln, aber eine geeignete Vorgehensweise, die Top-Down-Modellierung:

  • Man ermittelt die Klassen, die sich aus dem Sachzusammenhang ergeben.
  • Man fängt bei der "obersten" Klasse an, die über allem steht und arbeitet sich immer weiter nach unten durch. Dabei stellt man fest, welche Beziehung zwischen den Klassen besteht.
  • Man zeichnet ein Implementationsdiagramm, in dem die Beziehungen zwischen den Klassen festgehalten werden.
  • Man zeichnet Klassendiagramme für die einzelnen Klassen, in denen Attribute und Methoden festgehalten werden.

Beispiel für die EF

Szenario:

//TODO

Klassendiagramm:

Java-Quelltext:

In den Quelltexten sind fett gedruckt die Teile, die die Beziehungen zwischen den Klassen herstellen.

Klasse Person

public class Person
{
   private Roller meinRoller;
   private Tankstelle dieTankstelle;
   private String name;
   private double geld;
  
   public Person(String pName)
   {
       name = pName;
       meinRoller = new Roller();
   }
  
   public void setTankstelle(Tankstelle pTankstelle)
   {
     dieTankstelle = pTankstelle; 
   }
  
   public void geldErhoehen(double pBetrag)
   {
       geld += pBetrag;
   }
    
   public boolean geldVermindern(double pBetrag)
   {
       if(geld < pBetrag){
           return false;
       }
       geld -= pBetrag;
       return true;
   }
   
   public boolean tanken(double pLiter)
   {
       double kosten = dieTankstelle.tanken(pLiter);
       if(kosten > geld)
       {
           return false;
       }
       boolean erfolg = meinRoller.tanken(pLiter);
       if(erfolg == false)
       {
           return false;
       }
       geld -= kosten;
       return true;
   }
    
   public boolean fahren(double pKm)
   {
       boolean erfolg = meinRoller.fahren(pKm);
       return erfolg;
   }
}

Erklärung:

  • Die hat-Beziehung zwischen Person und Roller wird hergestellt, indem im Konstruktor von Person ein Roller erzeugt wird.
  • Dieser Roller wird im Attribut meinRoller gespeichert.
  • Die Person kann jetzt Aufgaben an meinRoller delegieren, indem sie geeignete Methoden von meinRoller aufruft.
  • Die kennt-Beziehung zwischen Roller und Tankstelle wird durch die Methode setTankstelle hergestellt.
  • Die Person kann jetzt das tanken an die Tankstelle delegieren.

Klasse Simulation

Diese Klasse erscheint nicht im Klassendiagramm, ist aber sinnvoll, um die Simulation überhaut starten zu können. Hier wird die Beziehung zwischen Person und Roller hergestellt.

public class Simulation
{
   private Person frank;
   private Tankstelle aral;
  
   public Simulation(){
       frank = new Person("Frank");
       aral = new Tankstelle("Aral");
       aral.setPreis(1.43);
       frank.setTankstelle(aral);
   }
}

Beispiel für die Q1 (Listen)

Szenario:

Ein Medienplayer kann die Titel, die man hören möchte, in Wiedergabelisten verwalten. Folgende typische Operationen sollen im Modell enthalten sein:

  1. Für einen Titel werden der Name, der Interpret und die Länge in Sekunden gespeichert. (Um die Speicherung der Audio-Daten kümmert sich diese Modellierung nicht.)
  2. Ein Titel kann an einer beliebigen Position der Wiedergabeliste (d. h. am Anfang, am Ende oder an einer Stelle innerhalb der Liste) eingefügt werden. Ebenso kann ein beliebiger Titel aus der Liste gelöscht werden.
  3. Das Abspielen der Wiedergabeliste beginnt beim ersten Titel. Dann werden alle Titel nacheinander abgespielt. Man kann das Abspielen stoppen. Und man kann wieder an den Anfang der Wiedergabeliste gehen.
  4. In einem Medienplayer werden beliebig viele Wiedergabelisten verwaltet. Jede Wiedergabeliste hat einen Namen. Der Medienplayer kann immer nur eine aktive Wiedergabeliste haben. Die aktive Liste kann abgespielt werden.
  5. Im Medienplayer kann man eine Wiedergabeliste auswählen, indem man ihren Namen angibt. Man kann auch neue Wiedergabelisten anlegen, indem man einen Namen angibt. Und man kann die gerade aktive Wiedergabeliste löschen.
  6. Beim Abspielen einer Wiedergabeliste fragt der Medienplayer immer den nächsten Titel von der aktiven Wiedergabeliste an.

Aufgabe:

Entwerfen Sie ein Implementationsdiagramm. Begründen Sie Ihre Entscheidungen. Begründen Sie auch, ob Sie sich für Stack, Queue oder List entscheiden.

Lösung

Analyse

Bei der Analyse schreibt man formelhaft Begründungen für die Beziehungen der Klassen:

  • Aus dem Szenario ergeben sich die Klassen Medienplayer, Wiedergabeliste und Titel.
  • Medienplayer ist die "oberste" Klasse und damit der Ausgangspunkt der Modellierung.
  • Medienplayer hat eine Liste mit Inhaltsobjekten vom Typ Wiedergabeliste. List eignet sich besser als Queue oder Stack, weil damit das Auswählen der Wiedergabeliste nach dem Titel einfacher realisiert werden kann.
  • Medienplayer hat ein Attribut aktiveWiedergabeliste vom Typ <Wiedergabeliste, in dem die jeweils aktive Wiedergabeliste gespeichert wird.
  • WiedergabeListe kann nicht von List erben, weil sie sonst die Methode concat(List pList) zur Verfügung hätte, die im Szenario nicht vorgesehen ist.
  • Stattdessen: WiedergabeListe hat eine List mit Inhaltsobjekten vom Typ Titel. Queue oder Stack eignen sich nicht, weil man an beliebigen Stellen einfügen können muss.


Implementationsdiagramm: Beziehung der Klassen

Zuerst werden nur die Beziehungen zwischen den Klassen in einem Diagramm dargestellt.

Attribute und Methoden werden noch nicht dargestellt. Das erleichtert WESENTLICH die Modellierung und das Zeichnen!

Medienplayer-beziehungen.png

Implementationsdiagramm: Die einzelnen Klassen

Jetzt werden die einzelnen Klassen mit Attributen und Methoden dargestellt.

Medienplayer-klassen.png