Definieren von Objekt-Beziehungenamrhein/ADP/Struktur.pdf · 2017-08-08 · 4 Szenario/Problem Auf...

Post on 11-Mar-2020

0 views 0 download

Transcript of Definieren von Objekt-Beziehungenamrhein/ADP/Struktur.pdf · 2017-08-08 · 4 Szenario/Problem Auf...

Strukturmuster

Definieren von Objekt-Beziehungen

2

Einleitung Strukturmuster beschreiben die

Zusammensetzung und die Beziehungen von Klassen und Objekten zu grösseren Strukturen.o Sie legen fest, welche Beziehungen Klassen

untereinander haben und was ihre Verantwortlichkeiten sind.

o Strukturmuster, welche sich auf Objekte beziehen, legen fest, welche konkreten Instanzen einer bestimmten Klasse gebildet werden.

Beispiele: Fassade, Adapter, Proxy, Decorator, Bridge, …

Fassade

Vereinfachte Schnittstelle

3

4

Szenario/Problem

Auf ein Subsystem mit komplexer innerer Struktur wird ein Zugriff benötigt.

Dies soll möglich sein, ohne den Clients die Details des Subsystems (Paket/Komponente) bekannt zu geben.

(Zu) viele verschiedene Zugriffe von aussen, komplex, unübersichtlich, …

5

Mögliche Lösung Das Fassade Design Pattern definiert eine

einfache Schnittstelle zur Benutzung eines Systems oder einer Menge von Objekten.

Eine Fassade vereinfacht den Zugriff auf ein komplexes Subsystem oder auf eine Menge zusammengehörender Objekte.

6

Anwendung des Pattern Das Fassade Pattern versteckt die Komplexität

des Subsystems und stellt den Clients eine Schnittstelle für die Benutzung des Subsystems zur Verfügung.

Mit dieser Schnittstelle können alle Clients uniform auf das System zugreifen.

Das Fassademuster fügt eine einzige neue Klasse zum Subsystem hinzu.

Die Fassade leitet alle von den Clients benötigten Methoden an die internen Systemklassen weiter.

7

Lösung/Implementation

Konkretes Beispiel: Fassade für ein Bookingsystem.

8

Lösung/Implementation

Fassade implementiert die vereinfachende

Schnittstellenfunktiondelegiert die auszuführenden Aufgaben an die

beteiligten Klassen des Subsystems weiter

Klassen im Paket implementieren die verschiedenen Dienste und

Methodendiese sind meistens nur im Paket (intern)

sichtbar (package)

9

Lösung/Struktur/Implementation

public class BookingFacade {

private Reservation reservation = new Reservation(); private Payment payment = new Payment(); private Confirmation confirmation = new Confirmation();

public String book(long eventId, long seatId) { String amount = reservation.reservate(eventId, seatId); payment.doPayment(amount); String message = confirmation.confirm(eventId, seatId); return message; }

}

10

Lösung/Struktur/Implementation

public class Reservation {

public String reservate(long eventId, long seatId) { // hier waere die Business Logik fuer die Reservation ... return "200"; }}

public class Payment {

public String doPayment(String amount) { // hier waere die Business Logik fuer die Bezahlung... return "ABC-1865227"; }}

public class Confirmation {

public String confirm(long eventId, long seatId) { // hier waere die Business Logik fuer das Bestaetigen via email ... return "Ok"; }}

11

Lösung/Struktur/Implementation

public class FacadeSampleApplication {

public static void main(String[] args) {BookingFacade bookingFacade = new BookingFacade();

bookingFacade.book(1,255);

}}

12

Vorteile Vereinfachte Schnittstelle. Der Client kann ein komplexes System einfach

verwenden, ohne die Klassen des Systems zu kennen. Entkopplung des Client vom Subsystem: Da die Clients

nur mit der Fassade arbeiten sind sie unabhängig von Änderungen im Subsystem.

Wartungen und Modifikationen am Subsystem bedeuten nur Änderungen innerhalb des Systems und ev. der Fassade.

Nachteile Eine zusätzliche Klasse mit zusätzlichen Methoden (Indirektion verlangsamt den Code)

13

Verwendung

Das Fassade Pattern ist sinnvoll anwendbar wenn ein neu zu erstellendes System/Subsystem mit

vielen unterschiedlichen Methoden in nicht verwandten Klassen von aussen benutzbar sein soll

sich die Schnittstelle auf das Subsystem nicht/nur selten ändert

sich die Signaturen der Methoden in diesen Klassen nicht / nur selten ändern

14

Praxisbeispiel Microservice-Fassade

Quelle: https://github.com/strongloop/loopback-example-facade/wiki/The-Microservice-Facade-Pattern

15

Verweis auf andere Muster

Verwandte Muster sind Adapter Pattern

- Umwandlung in „etwas anderes“ Wrapper Pattern

- Schnittstelle zu bestehendem Alt-System (z.B. nicht OO)

Bridge Pattern- Bridge entkoppelt eine Abstraktion

(Schnittstelle) von ihrer konkreten Implementierung (zweiseitige Verbindung / Unabhängigkeit).

Adapter

Schnittstellen-Anpassung

16

17

Szenario/Problem

Eine bestehende Menge von Klassen, eine Werkzeugsammlung oder eine Klassenbibliothek soll verwendet werden.

Die Schnittstelle der bestehenden Klassen oder Bibliotheken entspricht nicht der vom Client benötigten Schnittstelle.

18

Mögliche Lösung Das Adapter Design Pattern implementiert eine

Schnittstelle zum übersetzen der Anfragen in die Schnittstelle des vorhandenen Systems oder einer Klassenbibliothek.

19

Anwendung des Pattern Bibliotheken stellen ihre Dienste durch klar

definierte Schnittstellen zur Verfügung, welche nicht geändert werden sollen oder nicht geändert werden können.

Das Adapter Pattern kann benutzt werden, um bestehende Klassen oder Bibliotheken zu benutzen.

Der Adapter ermöglicht die Kommunikation zwischen nicht kompatiblen Schnittstellen.

20

Lösung/Implementation

Konkretes Beispiel: Adapter für eine existierende (-Bibliotheks)-Klasse

21

Lösung/Implementation

Konkretes Beispiel: Adapter für eine existierende Person(-Bibliotheks)-Klasse

22

Lösung

Adapter- implementiert die öffentlichen (public)

Schnittstellenfunktionen- übersetzt die Anfrage in die Schnittstelle der

Bibliothek und leitet die auszuführende Aufgaben an eine oder mehrere Klassen der Bibliothek

- übersetzt die so erhaltene Antwort in den korrekten Ziel-Typ.

23

Lösung/Struktur/Implementation

public class PersonAdapter{ private Person person;

public void setValid(boolean b) { if(b)

person.setValid(); else

person.setInvalid(); }

public String getName() { return person.getFirstname() + " " +

person.getLastName(); }

. . . }

24

Vorteile Der Client kann ein bestehendes System einfach

verwenden, ohne dass die Klassen des Systems angepasst werden müssen.

Es können Methoden verwendet werden, welche nicht der Ziel-Schnittstelle entsprechen (falsche Signatur/falscher Typ).

Austausch der Bibliothek einfach möglich (unter ev. Anpassung der Adapter-Klasse).

25

Nachteile (Indirektion verlangsamt ev. den Code)

Klassenhierarchie ist schwierig abzubilden (z.B.

Klasse Employee abgeleitet von Person).

26

Verwendung

Das Adapter Pattern ist sinnvoll anwendbar wenn

viele Methoden in bestehenden Klassen oder Bibliotheken benutzt werden sollen.

sich die Schnittstelle auf das die Bibliothek nicht/nur selten ändert.

Die Bibliothek flexibel austauschbar sein soll.

27

Praxisbeispiel Fassade/Adapter

Quelle: Software-Referenzarchitektur des EJPD

28

Verweis auf andere Muster

Verwandte Muster sind Wrapper Pattern

- Schnittstelle zu bestehendem Alt-System (z.B. nicht OO)

Proxy- kontrolliert den Zugang zu einer

Komponente oder einem Subsystem (Security)

Fassade- Schnittstelle in Paket oder Subsystem

29

ÜbungIm setter für Telefonnummer die Nummer validieren und formatieren:

public void setTelefonnummer(String telefonnummer) { // hier die Telefonnummer pruefen,formatieren und zuweisen, z.B.

this.telefonnummer = ???.validateAndFormatNumber(telefonnummer);}

Validieren und formatieren mit Google libphonenumber-Bibliothek, aber ohne dass Klasse Vereinsmitglied eine Abhängigkeit auf die Google Library hat. Google lib soll später ausgetauscht werden können, ohne dass Code in Vereinsmitglied ändert.

Proxy

Stellvertreter

30

31

Szenario/Problem

Der Zugriff auf ein Objekt soll aus einem (oder mehreren Gründen) auf einen Stellvertreter umgeleitet werden.

Gründe dafür können sein:a. Ein Objekt soll gegen unberechtigten Zugriff

geschützt werden.b. Der Zugriff auf ein Objekt soll aufgezeichnet

werden (Logging) .

c. Das benötigte Objekt ist nicht lokal verfügbar/vorhanden.

d. Ein grosses, komplexes Objekt soll nicht als ganzes, sondern es sollen nur die benötigten Teile davon geladen werden.

32

Mögliche Lösung Das Proxy Design Pattern implementiert einen

lokalen Stellvertreter (Remote Proxy) zum Weiterleiten oder Filtern der Anfragen.

Geeignet als Lösung für a, b und c

33

Mögliche Lösung Das Proxy Design Pattern implementiert einen

virtuellen Stellvertreter (Virtual Proxy) zum Filtern oder Verzögern der Anfragen (z.B. verzögertes Speichern).

Geeignet als Lösung für a, b und d

34

Anwendung des Pattern Ein Proxy (Stellvertreterobjekt) kann verwendet

werden um- Technische Aspekte hinzuzufügen, z.B.

Transaktionen, Security, Logging, ... - einen Zugriff auf „ferne“ Objekte zu bieten

(remote/über ein Netzwerk).- die Kosten für das Erzeugen komplexer Objekte

zu senken (z.B. durch dessen Verzögerung oder Vermeidung).

- den Zugriff auf Objekte aufzuzeichnen.

35

Lösung/Implementation

Proxy als Stellvertreter für ein reales Objekt.

36

Lösung/Implementation

Der Proxy- implementiert die öffentlichen

Schnittstellenfunktionen- erweitert oder filtert die Anfrage und leitet die

auszuführende Aufgaben (falls nötig) an das reale Objekt weiter.

- gibt die erhaltene Antwort an den Client zurück.

Reales Objekt- bietet verschiedene Dienste und Methoden

37

Lösung/Struktur

Image Proxy als Stellvertreter für ein reales Image Objekt.

Verzögerte Anzeige mit „Ersatzbild“ während des Ladens.

38

Lösung/Implementation

public class Proxy { private Image image;

public Dimension getSize(boolean b) { return image.Size() }

public void paint() { if(image != null) image.paint(); else { Anzeige: "Bild ist am Rendern…" Lade Bild in separatem Thread } }

. . . }

39

Vorteile Der Proxy kann bestehende Objekte gegen

unerlaubten Zugriff schützen, ohne dass das Objekt verändert werden muss.

Der Proxy kann die Funktionalität eines bestehenden Objekts einfach erweitern (Nebeneffekte).

Für den Client ist der Zugriff transparent. Ein Austausch des realen Objekts ist einfach möglich.

Nachteil Verlangsamung durch Indirektion.

40

Verwendung

Das Proxy Pattern kann verwendet werden, um bestehende Klassen/Objekte um gewisse Funktionalitäten wie Zugriffsschutz, Logging, verzögertes Laden, Remote-Zugriff, …zu erweitern.

Wird extensiv in Spring und Java Enterprise Edition eingesetzt.

41

Praxisbeispiel: Spring Transactions

Quelle: https://spring.io/blog/2012/05/23/transactions-caching-and-aop-understanding-proxy-usage-in-spring

42

Praxisbeispiel: Security Proxy

Quelle: Software-Referenzarchitektur des EJPD

43

Verweis auf andere Muster

Verwandte Muster sind (neben den bereits erwähnten)

Decorator- Dynamische Erweiterung von Klassen

um neue Funktionalität

Decorator

Funktionale Erweiterung

44

45

Szenario/Problem

Die Funktionalität von Objekten soll möglichst flexibel verändert oder erweitert werden können, ohne dass die Klasse geändert werden soll.

Gründe dafür können sein:a. Ein Objekt soll weitere Informationen zur

Verfügung stellenb. Ein Objekt soll weitere Dienste zur Verfügung

stellen.

c. Die bestehende Funktionalität eines Objekts soll flexibel angepasst oder erweitert werden können.

46

Szenario/Problem Es soll möglich sein, Dokumente oder

Bilder auf verschiedenste Art herzustellen:- Mit schmalem, mittlerem oder grossem

Rand- Kompakt oder hochauflösend- Mit oder ohne Border-Linien- Mit oder ohne Hintergrundfarbe- Mit oder ohne Wasserzeichen

47

Mögliche Lösung Das Decorator Design Pattern verwendet

verschiedene Komponenten, welche die unsprüngliche Komponente um zusätzliche Eigenschaften oder Funktionalität erweitern (aber ohne die Verwendung von Generalisierung!)

Dekorationen des FileInputStream in der Java LibraryQuelle: http://www3.ntu.edu.sg/home/ehchua/programming/java/j5b_io.html

48

Lösung/Struktur Der Methodenaufruf auf den Dekorierer wird vor den Aufruf

auf die zu dekorierende Komponente geschaltet. Der Dekorierer hat die gleiche Schnittstelle wie die zu

dekorierende Komponente. Aufrufe an den Dekorierer können entweder weitergeleitet

oder in der Komponente selber verarbeitet werden. Der Dekorierer ist dabei für den Aufrufer (Client)

transparent, der Client sieht den Dekorierer nicht.

49

Lösung/Struktur Das Interface definiert die

öffentliche Schnittstelle für die zu dekorierenden Objekte.

Der abstrakte Decorator hält eine Referenz auf die Komponente und implementiert sie gleich wie die Komponente.

Die konkreten Decorator implementieren die speziellen Operationen/Zusatz-Dienste.

50

Implementation

public interface IRenderer{ void render();}

51

Implementationpublic class Document : IRenderer{ public void render() { // render document Console.WriteLine("Render Document"); }}

public class Image : IRenderer{ public void render() { // render image Console.WriteLine("Render Image: "); }}

52

Implementationpublic abstract class DocumentDecorator : IRenderer{ protected IRenderer decoratedRenderer;

public DocumentDecorator(IRenderer decoratedRenderer) { this.decoratedRenderer = decoratedRenderer; }

virtual public void render() { decoratedRenderer.render(); }}

53

Implementationpublic class BorderDecorator : DocumentDecorator{ public BorderDecorator(IRenderer decoratedRenderer) :

base(decoratedRenderer) {}

override public void render() { decoratedRenderer.render(); setBorder(decoratedRenderer); }

private void setBorder(IRenderer decoratedRenderer) { // render border Console.WriteLine("-------------------------------"); Console.WriteLine("setBorder"); Console.WriteLine("-------------------------------"); }}

54

Implementationpublic class BackgroundDecorator : DocumentDecorator{ public BackgroundDecorator(IRenderer

decoratedRenderer) : base(decoratedRenderer)

{ }

override public void render() { decoratedRenderer.render(); setBackground(decoratedRenderer); }

private void setBackground(IRenderer decoratedRenderer) { // set Color Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine("Set Foreground red"); }}

55

ImplementationIRenderer document = new Document();document.render();

IRenderer borderedDocument = new BorderDecorator(new Document());

borderedDocument.render();

IRenderer colorborderImage = new BorderDecorator(new BackgroundDecorator(new Image()));

colorborderImage.render();

56

Vorteile Die zu dekorierende Klasse ist beliebig (so lange sie

die Schnittstelle implementiert). Für den Client ist der Zugriff transparent. Ein Austausch des realen Objekts ist einfach möglich. Mehrere Decorator können hintereinander

geschachtelt werden. Lange und unübersichtliche Vererbungshierarchien

können vermieden werden. Jeder Decorator repräsentiert genau seine Funktion

(und nichts sonst) -> einfacher, wartbarer Code.

57

Nachteile Erschwerte Fehlerfindung bei langen, versteckten

Aufrufketten von dekorierten Objekten. Viele Klassen und Objekte, da für jedes Feature

ein neuer Dekorierer gebraucht wird. Das dekorierte Objekt hat nicht die gleiche

Identität wie das ursprüngliche Objekt, Vorsicht bei Aufruf von equals().

58

Praxisbeispiel: Angular Decorator@Component({ selector: 'app-recipe-detail', templateUrl: './recipe-detail.component.html', styleUrls: ['./recipe-detail.component.css']})export class RecipeDetailComponent implements OnInit { @Input() recipe: Recipe;

constructor() { }

ngOnInit() { }

}

59

Verweis auf andere Muster

Verwandte Muster sind (neben den bereits erwähnten)

Pipes and FilterKette von Objekten (Filtern), welche die

zusätzlichen Anfragen oder Aufgaben hintereinander ausführen.

60

Übung

Ordnen Sie die Aussagen den Pattern zu:

Fassade Fungiert als Stellvertreter für das reale Objekt

Adapter Konvertiert ein Interface in ein anderes

Proxy Belässt das Interface unverändert, aber addiert Zusatzfunktionalität

Decorator Vereinfacht den Zugriff auf ein Subsystem

Zusammenfassung

Vergleich

61

62

Kurzbeschreibung Ein Adapter passt eine

existierende Schnittstelle an die vom Client benötigte Schnittstelle an.

Eine Fassade vereinfacht den Zugriff auf ein komplexes Subsystem.

Ein Decorator fügt einer Komponente dynamisch neue Funktionalität zu.

Ein Proxy ist ein Platzhalter für ein anderes Objekt.

63

Unterscheidungsmerkmale Eine Fassade erzeugt ein neues Interface, ein Adapter

benutzt ein bestehendes Interface (und wandelt es um).

Ein Adapter ermöglicht die Benutzung bestehender Software auf eine «neue» Art.

Eine Fassade leitet eine Anfrage weiter, ein Adapter wandelt ein Objekt (Anfrage/ Antwort) um.

Ein Proxy erweitert die Funktionalität (einmalig) und behält dabei die Schnittstelle (keine Umwandlung).

Ein Decorator erweitert die Funktionalität rekursiv bei gleicher Schnittstelle und ohne Ableitung (subclassing).