• Keine Ergebnisse gefunden

Klassendiagramme—Modellierung und Implementation

N/A
N/A
Protected

Academic year: 2021

Aktie "Klassendiagramme—Modellierung und Implementation"

Copied!
51
0
0

Wird geladen.... (Jetzt Volltext ansehen)

Volltext

(1)

Klassendiagramme—

Modellierung und Implementation

OOPM, Ralf Lämmel

Eigentlich ein

Verkehrsschild -- schaut

aber wie UML aus!?

(2)

Motivation: Wir wollen die Struktur für eine Anwendung im Personalwesen modellieren.

MSFT

VB C#

HR Dev

Anders Erik

Paul

Firma

Abteilungen Unter-

abteilungen

Angestellte

(3)

Ein Klassendiagramm

für eine Anwendung im Personalwesen

(4)

Beziehungen im OO Paradigma

Auf Objektebene

Verknüpfungen zwischen Objekten Auf Typebene (Klassen / Schnittstellen)

Generalisierung

Eine Klasse spezialisiert eine andere Klasse.

Ein Schnittstelle spezialisiert eine andere Schnittstelle.

Eine Klasse realisiert eine Schnittstelle.

Mehrfachvererbung Assoziationen

Modellierung von Verknüpfungen auf Typebene

(5)

Fahrplan

Relevante Sprachmittel für Klassenbeziehungen in Java UML-Notation für Beziehungen in Klassendiagrammen Abwägung von Vererbung vs. Komposition

Abbildung von UML’s Beziehungen auf Java

(6)

Ein Beispiel

Eine Klasse für Zähler (Counter) Zustand

Zählerstand Verhalten

Zähler erhöhen (“step”) Zählen ablesen (“read”)

Zähler zurücksetzen (“reset”)

Siehe Counter Chrestomathie

https://github.com/rlaemmel/nopetal

(7)

* A simple class of counters */

public class BasicCounter {

/** Private state of the counter */

private int count = 0;

/** Increment the counter */

public void step() { count++; }

/** Return the value of the counter */

public int read() { return count; } /** Reset the counter to zero */

public void reset() { count = 0; }

(8)

Objektverwendung

BasicCounter mycounter = new BasicCounter();

mycounter.step();

mycounter.step();

mycounter.step();

System.out.println(mycounter.read());

Ausgabe: 3

(9)

Veränderte Anforderung

(Realisierung mit Klassenvererbung)

Zähler mit Grenze (“limit”) Zustand

Limit

Modifiziertes Verhalten

Zähler erhöhen (“step”)

(10)

/**

* A counter whose count is limited */

public class LimitedCounter extends BasicCounter { private int limit;

/** Construct a limited counter from the limit */

public LimitedCounter(int i) { limit = i;

}

/** Stop stepping when the limit is reached */

public void step() { if (read() < limit) super.step();

}

}

Aufruf der Implementation

der Oberklasse

(11)

Veränderte Anforderung

(Realisierung mit Klassenvererbung)

Zähler mit Erinnerung (“recall”) Zustand

Geretteter Wert (“snap”) Zusätzliches Verhalten

Retten des Wertes (“mark”)

(12)

/**

* A counter with recall */

public class RecallCounter extends BasicCounter { private int snap = read();

/** Store the counter state until later */

public void mark() { snap = read();

}

/** Reset the counter for recall */

public void recall() { count = snap;

} }

Oops!

Unzulässiger Zugriff auf “count”!

(13)

* A simple class of counters */

public class BasicCounter {

/** Protected state of the counter */

protected int count = 0;

/** Increment the counter */

public void step() { count++; }

/** Return the value of the counter */

public int read() { return count; } /** Reset the counter to zero */

public void reset() { count = 0; }

Gewährung von Zugriff für

Unterklassen

(14)

Beschränkung der Veerbung

Finale Klasse

Kann nicht spezialisiert werden Beschränkt Typsubstitution

Finale Methode

Kann nicht überschrieben werden

Beschränkt Verhaltensänderungen

(15)

* A counter that cannot be extended any further */

public final class FinalCounter extends BasicCounter { }

(16)

Variation im OO Entwurf

Identifikation einer Schnittstelle für Zähler Abstraktion von jeglicher Implementation Warum?

Lässt die Oberklasse offen

Nicht so wichtig für triviale Zähler!

Interessant für komplexere Datenstrukturen

(17)

* The shared interface of counters */

public interface Counter {

/** Increment the counter */

void step();

/** Return the value of the counter */

int read();

/** Reset the counter to zero */

void reset();

}

(18)

/**

* A simple class of counters */

public class BasicCounter implements Counter { // Private state of the counter

protected int count = 0;

/** Increment the counter */

public void step() { count++; }

/** Return the value of the counter */

public int read() { return count; } /** Reset the counter to zero */

public void reset() { count = 0; } }

(19)

Wieder Zähler mit Grenze

mit Wiederverwendung aber ohne Vererbung

Benutzung von Assoziation

Verknüpfung zu Zähler ohne Grenze Delegation von Nachrichten

Warum?

Variation

im OO Entwurf

(20)

/**

* A counter whose count is limited */

public class LimitedCounter implements Counter { private BasicCounter inner = new BasicCounter();

private int limit;

/** Construct a limited counter from the limit */

public LimitedCounter(int i) { limit = i; } /** Return the value of the counter */

public int read() { return inner.read(); } /** Reset the counter to zero */

public void reset() { inner.reset(); }

/** Stop stepping when the limit is reached */

public void step() {

if (read() < limit) inner.step();

}

Delegation

Delegation

(21)

Wieder Zähler mit Erinnerung mit Wiederverwendung aber ohne Vererbung

Benutzung von Assoziation

Variation

im OO Entwurf

(22)

public class RecallCounter implements Counter {

private BasicCounter inner = new BasicCounter();

private int snap = inner.read();

/** Increment the counter */

public void step() { inner.step(); } /** Return the value of the counter */

public int read() { return inner.read(); } /** Reset the counter to zero */

public void reset() { inner.reset(); }

/** Store the counter state until later */

public void mark() { snap = read(); } /** Reset the counter for recall */

public void recall() { inner.count = snap; } }

Oops!

Unzulässiger Zugriff auf “count”! Oops!

(23)

* A simple class of counters */

public class BasicCounter implements Counter { // Package-private state of the counter

/* default */ int count = 0;

/** Increment the counter */

public void step() { count++; }

/** Return the value of the counter */

public int read() { return count; } /** Reset the counter to zero */

public void reset() { count = 0; }

Gewährung von Zugriff für

Klassen im

Package

(24)

Zugriffskontrollen

public

Zugriff darf von überall erfolgen private

Zugriff nur innerhalb der Klasse protected

Zugriff in der Klasse und Unterklassen

“default”

Zugriff überall innerhalb des Packages

Synonyme:

“friendly” und

“package

private”

(25)

Beziehungen im OO Paradigma

Auf Objektebene

Verknüpfungen zwischen Objekten Auf Typebene (Klassen / Schnittstellen)

Generalisierung

Eine Klasse spezialisiert eine andere Klasse.

Ein Schnittstelle spezialisiert eine andere Schnittstelle.

Eine Klasse realisiert eine Schnittstelle.

Mehrfachvererbung

(26)

Einfach- & Mehrfachvererbung

Erbt eine Klasse nur von einer anderen Klasse, so spricht man von Einfachvererbung. Sind es

mehrere Klassen, von denen geerbt wird, so

bezeichnet man dies mit Mehrfachvererbung.

(27)

Mehrfachvererbung

Zulässig in UML und C++ u.a.

Unklarheiten / Probleme / Risiken Direkte Konflikte (siehe payMeal) Indirekte Konflikte (siehe name) Mehrfachvererbung in Java

Nicht zulässig für Klassen

Zulässig für Schnittstellen

(28)

Mehrfachvererbung in UML

(ein weiteres Beispiel)

(29)

Eine Klasse kann mehrere

Schnittstellen implementieren.

(30)

Beziehungen im OO Paradigma

Auf Objektebene

Verknüpfungen zwischen Objekten Auf Typebene (Klassen / Schnittstellen)

Generalisierung

Eine Klasse spezialisiert eine andere Klasse.

Ein Schnittstelle spezialisiert eine andere Schnittstelle.

Eine Klasse realisiert eine Schnittstelle.

Mehrfachvererbung Assoziationen

Modellierung von Verknüpfungen auf Typebene

(31)

Assoziationen

Allgemeine Assoziation Teil-Ganzes Beziehungen

Aggregation

Komposition

(32)

Allgemeine Assoziationen

Zwei Klassen gehen eine Beziehung ein.

Modelliert Verbindungen zwischen Instanzen Multiplizität der Verbindung ist festzulegen

Gerichtete Verbindungen sind nur einseitig navigierbar Beispiel

Ein Konto hat einen (1) zugeordneten Kunden.

Ein Kunde besitzt beliebig viele (0..*) Konten.

(33)

Teile-Ganzes-Beziehungen

Aggregation

Alle Multiplizitäten sind zulässig

Unausgefüllte Raute am Ende des Ganzen Komposition

Stärkere Form der Aggegration

Multiplizitäten 1 und 0..1 zulässig für das Ganze Ausgefüllte Raute am Ende des Ganzen

Beispiel

Eine Abbildung besteht aus beliebig vielen Formen.

Siehe Shapes Chrestomathie

https://github.com/rlaemmel/nopetal

(34)

Unterscheidung von

Aggregation und Komposition

Betrachte die Beziehung zwischen Klassen für Fahrzeuge und Motoren. Ein Motor ist definitiv ein Teil des Fahrzeugs.

Nehmen wir weiterhin an, dass die Klassen technische Entwürfe modellieren. Dann kann ein Motor Teil mehrerer Fahrzeuge sein.

Aggregation ist adäquat.

Komposition wäre stattdessen adäquat, wenn die Klassen

physische Fahrzeuge (und deren Komposition aus echten

Teilen) modellieren. Jedes Teil kann dann nur einmal

(35)

Abwägung zwischen

Generalisierung und Assoziation

(36)

Kombination aus

Generalisierung und Assoziation

(37)

Java-Implementation von UML-Assoziationen

Variationen

Gerichtet und ungerichtet

Multiplizitäten 0..1, 1, 0..*, 1..*

Allgemein vs. Aggregation (Komposition)

(Assoziationsklassen (Assoziationen mit Attributen)) (Mehrfachgeneralisierungen (für Klassen))

Wir werden die (wenigen) speziellen Herausforderungen von

https://svn.code.sf.net/p/developers/code/repository/

oopm/eclipse/chrestomathy/oo/assoc/

(38)

Modell

Jede Person hat möglicherweise eine Residenz.

Jede Residenz beherbergt beliebig viele Personen.

Navigation ist nur von Person nach Residenz vorgesehen.

Implementation

Klasse Person hat Feld vom Typ Residence.

Das Feld darf legal den Wert “null” annehmen.

“0..1”

(39)

/**

* A person with an optional residence */

public class Person {

private Residence residence;

public Residence getResidence() { return residence;

}

public void setResidence(Residence residence) { this.residence = residence;

} }

Auslassungen der

Einfachheit halber: Attribute für Name, Straße, o.ä. sowie

Konstruktoren zur

Initialisierung sowie Getter und Setter für den Zugriff

auf die ausgelassenen

Attribute.

(40)

Objektverwendung

Residence r1 = new Residence("Bismarckstr. 37");

Residence r2 = new Residence("Bahnhofplatz 42");

Person p1 = new Person("Hans");

p1.setResidence(r1);

p1.setResidence(r2);

System.out.println(p1.getResidence().getStreet());

Ausgabe:

Bahnhofplatz 42

(41)

Modell

Jede Person hat genau eine Residenz.

Sonst wie vorher.

Implementation

Konstruktion einer Person benötigt eine Residenz.

Parameter des Konstruktors

Erzeugen des Residenzobjektes

“1”

(42)

Jede Person hat genau eine Residenz.

Überprüfung des Parameterkonstruktors

public class Person {

private Residence residence;

/** Construction requires a residence */

public Person(Residence residence) { if (residence==null)

throw new IllegalArgumentException();

setResidence(residence);

} ...

}

Vordefinierte

Ausnahmeklasse

(43)

Ableitungsposition von IllegalArgumentException

Heute: Erwähnung von Ausnahmen

(44)

Modell

Jede Person hat beliebig viele Residenzen.

Sonst wie vorher.

Implementation

Das Feld für die Residenzen ist von einem Container-Typ.

“0..*”

(45)

Jede Person hat beliebig viele Residenzen.

Verwendung eines Containers

public class Person {

private List<Residence> residences =

new LinkedList<Residence>();

...

}

(46)

Objektverwendung

Residence r1 = new Residence("Bismarckstr. 37");

Residence r2 = new Residence("Bahnhofplatz 42");

Person p1 = new Person("Hans");

p1.getResidences().add(r1);

p1.getResidences().add(r2);

for (Residence r : p1.getResidences()) System.out.println(r.getStreet());

Ausgabe:

Bismarckstr. 37

Bahnhofplatz 42

(47)

Modell

Jede Person hat beliebig viele Residenzen.

Die Navigation kann in beide Richtungen erfolgen.

Implementation

Wir brauchen Attribute für Verknüpfungen auf beiden Seiten.

Die Attribute sind von einem Container-Typ.

add/remove-Operation werden beidseitig angewandt.

“0..*”

“ungerichtet” und

(48)

Jede Person hat beliebig viele Residenzen.

Verwendung eines Containertyps.

public class Person {

??? List<Residence> residences;

...

}

public class Residence {

??? List< Person> persons;

...

}

Vertiefung: Vorlesungen zu ADTs und Generics

https://svn.code.sf.net/p/developers/code/repository/

oopm/eclipse/chrestomathy/oo/assoc/

(49)

Objektverwendung

Residence r1 = new Residence("Bismarckstr. 37");

Residence r2 = new Residence("Bahnhofplatz 42");

Person p1 = new Person("Hans");

p1.addResidence(r1);

r2.addPerson(p1);

for (Residence r : p1.getResidences()) System.out.println(r.getStreet());

Ausgabe:

(50)

Assoziationsklassen

(Assoziationen mit Attributen)

Damit ist auch die

Implementation klar.

(51)

Zusammenfassung

Struktur wird mit UML’s Klassendiagrammen modelliert.

Struktur wird mit Java’s Klassen implementiert.

Man muss Vererbung vs. Objektkomposition abwägen.

Man muss Sichtbarkeit regeln.

Ausblick

Spezifikation und Implementation von Datentypen Programmieren mit Ausnahmen

Programmieren mit Generics

Referenzen

ÄHNLICHE DOKUMENTE

§ Um ein Element zur Liste hinzuzufügen müssen wir das next Attribut des vorherigen Knotens modifizieren?.

§ Um ein Element zur Liste hinzuzufügen müssen wir das next Attribut des vorherigen Knotens modifizieren..

§ Variable, die in einer Methode deklariert sind, müssen einen Wert haben, bevor sie als Operand oder Parameter.. verwendet

§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.. § Wie durchlaufen wir

§ ListNode s können zu einer Kette verbunden (“linked”) wer- den um eine Menge oder Liste von Werten zu

§ Um ein Element zur Liste hinzuzufügen (oder zu von der Liste zu entfernen) müssen wir das next Attribut des vorherigen Knotens modifizieren.

Im Rahmen der Zweckmässigkeitsbeurteilung (ZMB) zu einer neuen ÖV-Achse in Biel werden nebst der Zweckmässigkeit von neuen Haltestellen auch verschiedene

Vom Endpreis eines Videorecorders (Preis einschließlich 19 % MWSt) werden 2 % Skonto abgezogen.. Berechnen Sie die tatsächliche prozentuale Änderung des