Sdv 0405 design-pattern_thc_jps_skript
Upcoming SlideShare
Loading in...5
×
 

Sdv 0405 design-pattern_thc_jps_skript

on

  • 411 views

 

Statistics

Views

Total Views
411
Views on SlideShare
411
Embed Views
0

Actions

Likes
0
Downloads
2
Comments
0

0 Embeds 0

No embeds

Accessibility

Categories

Upload Details

Uploaded via as Adobe PDF

Usage Rights

© All Rights Reserved

Report content

Flagged as inappropriate Flag as inappropriate
Flag as inappropriate

Select your reason for flagging this presentation as inappropriate.

Cancel
  • Full Name Full Name Comment goes here.
    Are you sure you want to
    Your message goes here
    Processing…
Post Comment
Edit your comment

Sdv 0405 design-pattern_thc_jps_skript Sdv 0405 design-pattern_thc_jps_skript Presentation Transcript

  • Entwurfsmuster ... in Java Carsten Thelen und Jan Philipp Seng Betreut von Dipl.-Inform., MaTA Bodo Kraft
  • Inhaltsverzeichnis 1 Muster 5 1.1 Was ist ein Muster? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 5 1.2 Kategorien von Mustern . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 6 2 Was ist ein Entwurfsmuster? 8 2.1 Vier grundlegende Elemente eines Entwurfsmusters . . . . . . . . . . . . . . . . . . . 8 2.2 Grundlegende Muster nach GoF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 9 3 Erzeugungsmuster (Creational-Pattern) 11 3.1 Erzeugungsmuster nach GoF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11 3.2 Fabrik (Factory) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3.3 Quellcode: WarenFactory . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13 4 Strukturmuster (Structure Pattern) 14 4.1 Strukturmuster nach GoF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14 4.2 Adapter (Adapter) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 4.3 Fassade (Facade) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 4.4 Kompositum (Compositum, Container) . . . . . . . . . . . . . . . . . . . . . . . . . 17 4.5 Quellcode: Container . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19 5 Verhaltensmuster (Behavior Pattern) 20 5.1 Verhaltensmuster nach GoF . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20 5.2 Beobachter (Observer) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 5.3 Quellcode Beispiel - Beobachter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 22 5.4 Model View Controller (MVC) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 5.5 Model View Controller in JAVA Swing . . . . . . . . . . . . . . . . . . . . . . . . . . 27 5.6 Quellcode: für Java Swing - SuchStringComboBoxModel . . . . . . . . . . . . . . . . 28 5.7 Strategie (Policy) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 6 Weitere Muster 30 7 Vor- und Nachteile von Entwurfsmustern 31
  • 8 Schlussbemerkung 32 9 Musterkatalog 33 9.1 Erzeugungsmuster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.2 Strukturmuster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33 9.3 Verhaltensmuster . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34 10 Abbildungsverzeichnis 36 11 Literaturverzeichnis 38 11.1 Literaturliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 11.2 Online Literaturliste . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38 12 Verwendete Notationen 39 12.1 Klassendiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 12.2 Objektdiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 12.3 Interaktionsdiagramme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 13 Impressum 43
  • 5 1 MUSTER 1 Muster Nicht jeder Software-Entwickler soll das Rad neu erfinden. Aber woher soll ein unerfahrener Software- Entwickler eine systematische, bewährte Lösungsstrategie kennen, wenn diese sich als Erfahrungswissen verbreitet? Nach Assembler und strukturierter Programmierung ist die Softwareentwicklung nun bei der Objektori- entierung angelangt. Dahinter zeichnet sich bisher kein weiteres revolutionäres Programmierparadigma ab. Objektorientierung allein reicht jedoch nicht aus, um ein gutes Softwaredesign zu garantieren. Es fehlt eine Ebene oberhalb der einzelnen Klassen und Objekten. Die Objekte selbst sind nicht das Problem, vielmehr ist es ihre Kopplung. Hier helfen Regeln, die unter dem Stichwort Muster (Pattern) bekannt geworden sind. Muster helfen dabei, das Wissen erfahrener Software-Ingenieure zu nutzen. Sie halten deren Erfahrungen in der Software-Entwicklung fest und helfen, die Qualität von Entwurfsentscheidungen zu verbessern. Jedes Muster befasst sich mit einem speziellen Problem, das beim Entwurf oder bei der Implementierung von Software-Systemen häufig auftritt. Mit Hilfe von Mustern lassen sich gezielt Software-Architekturen mit bestimmten Eigenschaften entwickeln. 1.1 Was ist ein Muster? Wenn Fachleute an einem Problem arbeiten, dann erfinden sie normalerweise keine völlig neue Lösung. Zumindest erinnern sie sich an ein ähnliches Problem, das sie bereits gelöst haben, und verwenden die Grundidee seiner Lösung, um ihr aktuelles Problem zu lösen. Ein solches Verhalten - das Denken in Problem-Lösungs-Paaren - tritt in vielen verschiedenen Bereichen auf, zum Beispiel in der Architektur, in den Wirtschaftswissenschaften und in der Software-Technik. Fachleute der Software-Technik kennen Muster aus ihrer praktischen Arbeit und benutzen sie bei der Entwicklung von Software-Anwendungen, die speziellen Anforderungen genügen sollen. Sie setzen sie ein, um Entwurfsprobleme wirksam und elegant zu lösen. Das Abstrahieren von konkreten Problem-Lösungs-Paaren und das Herausziehen der Gemeinsamkeiten aus diesen führt zu Mustern: Diese Problem-Lösungs-Paare zerfallen auf natürliche Art so in Gruppen von ähnlichen Problemen und Lösungen, dass sowohl für die Probleme als auch für die Lösungen ein Muster erkennbar ist. R.Johnson: An Introduction to Patterns, Reports on Object Analysis and Design [9] Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 1 MUSTER 6 1.2 Kategorien von Mustern Ein Studium existierender Musterbeschreibungen zeigt, dass sie Software von ganz unterschiedlichem Umfang betreffen und auf verschiedenen Abstraktionsebenen liegen. Einige Muster helfen dabei, ein Software-System durch die Einführung von Subsystemen zu strukturieren. Andere Muster unterstützen die Vereinfachung von Subsystemen und Komponenten oder die Beziehungen zwischen ihnen. Wieder andere Muster helfen dabei, spezielle Aspekte des Entwurfs in bestimmten Programmiersprachen aus- zudrücken. Muster können vollständig unabhängig von dem Anwendungsgebiet sein, wie zum Beispiel Muster für Entkopplung von interagierenden Komponenten. Andere Muster berühren Aspekte, die für bestimmte Anwendungsgebiete typisch sind, wie zum Beispiel Transaktionsstrategien in Geschäftsan- wendungen. Wir gruppieren Muster in drei Kategorien: • Architekturmuster, • Entwurfsmuster, • Idiome. Jede Kategorie fasst Muster zusammen, die Software-Systeme desselben Umfangs betreffen oder auf gleicher Abstraktionsebene liegen. Architekturmuster haben dabei den höchsten Abstraktionsgrad, Idio- me den niedrigsten. 1.2.1 Architekturmuster Ein Architekturmuster spiegelt ein grundsätzliches Strukturierungsprinzip von Software-Systemen wi- der. Es beschreibt eine Menge vordefinierter Subsysteme, spezifiziert deren jeweiligen Zuständigkeits- bereich und enthält Regeln zur Organisation der Beziehungen zwischen den Subsystemen. Im Architek- turentwurf (Systementwurf), wird beispielsweise festgelegt: • Anbindung der Benutzeroberfläche, • Anbindung der Datenhaltung, • Verteilung der Anwendung auf verschiedene, vernetzte Computersysteme 1.2.2 Entwurfsmuster Ein Entwurfsmuster beschreibt ein Schema zur Vereinfachung von Subsystemen oder Komponenten eines Software-Systems oder den Beziehungen zwischen ihnen. Es beschreibt eine häufig auftretende Struktur von miteinander kommunizierenden Komponenten, die ein allgemeines Entwurfsproblem in einem speziellen Kontext lösen. Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 7 1.2 Kategorien von Mustern 1.2.3 Idiome Ein Idiom ist ein für eine bestimmte Programmiersprache spezifisches Muster auf einer niedrigen Ab- straktionsebene. Es beschreibt, wie spezielle Aspekte von Komponenten oder den Beziehungen zwischen ihnen mit den Mitteln der Programmiersprache implementieren werden können. Wir wollen es bei dieser groben Unterteilung von Mustern belassen, auch wenn eine feinere Unterteilung möglich ist. Die Grenzen zwischen Mustern sind fließend. Starre Grenzen würden den kreativen Prozess der Softwa- reentwicklung eher blockieren als unterstützen. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 2 WAS IST EIN ENTWURFSMUSTER? 8 2 Was ist ein Entwurfsmuster? Ein Entwurfsmuster beschreibt eine generische Lösung eines wiederkehrenden Entwurfsproblems, die sich in der Praxis bewährt hat. Christoph Alexander schreibt: „Jedes Muster beschreibt ein in unserer Umwelt beständiges wiederkehrendes Problem und erläutert den Kern der Lösung für jedes Problem, so dass Sie diese Lösung beliebig oft anwenden können, ohne sie jemals ein zweites Mal gleich auszuführen.“ Christopher Alexander : A Pattern Language [2] Dass dieses Zitat aus dem Jahre 1977 stammt, mag verwunderlich sein, denn die objektorientierte Pro- grammierung war zu dieser Zeit noch nicht besonders weit verbreitet. Es stammt auch nicht aus der Software-Technik, sondern aus der Architekturtheorie. Christopher Alexander, der als Vater der Ent- wurfsmuster (design patterns) gilt, bezieht sich dabei auf Strukturen von Gebäuden und Städten. Diese Strukturen werden von ihm in Muster (patterns) unterteilt und verknüpft. Alexanders Ideen wurden von der so genannten „Gang of Four“ auf die Informatik übertragen, was die heutige Methodik der Softwareentwicklung wesentlich beeinflusst hat. Mit der „Gang of Four“ (oft als GoF abgekürzt) sind Erich Gamma, Richard Helm, Ralph Johnson und John Vlissides gemeint. Diese vier schrieben das Buch „Design Patterns - Elements of Reusable Design“, das als Standardwerk zum Thema Entwurfsmuster gilt. 2.1 Vier grundlegende Elemente eines Entwurfsmusters Im Allgemeinen besitzt ein Entwurfsmuster vier grundlegende Elemente: • Mustername Der Name eines Entwurfsmusters bringt die Idee oft bildhaft auf den Punkt. Dadurch wird die Verwendung der Musterideen in Diskussionen, Dokumentationen und Denkprozessen möglich. • Problemabschnitt und Kontext Entwurfsmuster können nur in bestimmten Umgebungen eingesetzt werden - dem Kontext. Der Kontext kann sehr allgemein gehalten sein aber auch sehr konkret beschränkt sein. Meist schließt der Kontext eine Reihe von Bedingungen ein, die erfüllt werden müssen, bevor man ein Entwurfs- muster anwenden kann, wie z.B. Codeumfang, Anpassbarkeit, Einhaltung bestimmter Protokolle, Geschwindigkeit, Speicherverbrauch oder Erweiterbarkeit. • Lösungsabschnitt Die Lösung stellt eine Vorlage dar, nach der Probleme dieser Art gelöst werden können. Dabei werden nicht immer alle Anforderungen erfüllt. Bei konkreter Anwendung muss ein Entwurfs- muster immer auf die jeweilige Situation angepasst werden. Die grundlegende Idee bleibt jedoch erhalten. Eine Lösung besteht aus einer statischen Struktur und einem Verhalten. In der Struktur werden die Elemente der Lösung und deren Beziehungen aufgeführt. Man kann auch von einer Micro- Architektur sprechen. Jedem Element werden bestimmte Aufgaben zugeordnet. Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 9 2.2 Grundlegende Muster nach GoF In der Verhaltensbeschreibung werden die dynamischen Aspekte der Lösung verdeutlicht: Wel- che Elemente miteinander kommunizieren, wie Elemente erzeugt oder vernichtet werden und die Reihenfolge von Aktionen. • Konsequenzenabschnitt Die Konsequenzen ergeben sich aus der Lösung. Es werden die Vor- und Nachteile gegeneinan- der abgewogen. Flexibilität, Erweiterbarkeit und Portabilität werden dabei besonders betont. Aber auch Auswirkungen auf die Implementierung werden aufgezeigt. 2.2 Grundlegende Muster nach GoF Nach GoF (Gang of Four) [8] werden Muster in drei Kategorien eingeteilt, die nach der Wirkung des jeweiligen Musters unterscheiden werden: • Erzeugungsmuster beziehen sich auf die Erzeugung von Objekten. Dadurch läßt sich die Anzahl von erzeugten Objekten einer Klasse kontrollieren, oder den konkreten Typ der erzeugten Objekte, abhängig von Laufzeitbedingungen, anpassen. • Strukturmuster liefern Muster, welche eine Vereinfachung der Struktur zwischen Komponenten ermöglichen. Komplexe Beziehungsgeflechte können beispielsweise über vermittelnde Kompo- nenten oder Schnittstellen logisch vereinfacht werden. Eine Komponente ist Teil eines Systems oder kann Teil eines Systems sein. Eine Komponente grenzt sich durch bestimmte kontextspezifi- sche Kriterien vom Rest des Systems ab. Diese Kriterien beziehen sich auf den jeweiligen Kontext, in dem der Begriff „Komponente“ verwendet wird. • Verhaltensmuster betreffen das Verhalten der Komponenten. Hierbei handelt es sich um die größ- te Gruppe von Mustern. Sie beziehen sich auf die Zusammenarbeit und den Nachrichtenaustausch von Komponenten. Weiterhin werden kategorieübergreifend klassenbasierte und objektbasierte Muster unterscheiden. • Klassenbasierte Muster behandeln Beziehungen zwischen Klassen und werden durch Vererbung ausgedrückt. – Klassenbasierte Erzeugungsmuster verlagern Teile der Objekterzeugung in Unterklassen. – Klassenbasierte Strukturmuster nutzen Vererbung, um Klassen zusammenzufügen. – Klassenbasierte Verhaltensmuster verwenden Vererbung, um Algorithmen und einen Kon- trollfluß zu beschreiben. • Objektbasierte Muster beschreiben Beziehungen zwischen Objekten. – Objektbasierte Erzeugungsmuster delegieren Teile der Objekterzeugung an ein anderes Objekt. – Objektbasierte Strukturmuster beschreiben Wege, um Objekte zusammenzuführen. – Objektbasierte Verhaltensmuster beschreiben, wie eine Gruppe von Objekten zusammen- arbeitet. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 2 WAS IST EIN ENTWURFSMUSTER? 10 2.2.1 Organisation des Katalogs der Entwurfsmuster nach GoF Die folgende Grafik zeigt die von GoF aufgeführten Entwurfsmuster und ihre Zuordnung zu den ver- schiedenen beschriebenen Kategorien. Abbildung 1: Organisation des Katalogs der Entwurfsmuster nach GoF Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 11 3 ERZEUGUNGSMUSTER (CREATIONAL-PATTERN) 3 Erzeugungsmuster (Creational-Pattern) Erzeugungsmuster beschreiben Vorgehensmodelle zur Erzeugung von Objekten. Der Erzeugungsprozess wird vor dem Entwickler bzw. Benutzer versteckt. Ein System wird dadurch unabhängiger von der Er- zeugung, Zusammensetzung und Repräsentation von Objekten. Weiterhin können konkrete Objekte abhängig von Laufzeitbedingungen erzeugt werden. Dieses Vorge- hen schafft Flexibilität. Zusätzlich sind die Erbauerklassen leicht wieder verwendbar. Die Konstruktion eines komplexen Objektes wird von dessen Repräsentation getrennt. 3.1 Erzeugungsmuster nach GoF Nach GoF gibt es folgende Erzeugungsmuster: • Abstrakte Fabrik (Abstract Factory, Kit) • Erbauer (Builder) • Fabrikmethode (Factory Method, Virtual Constructor) • Prototyp (Prototype) • Einzelstück (Singleton) Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 3 ERZEUGUNGSMUSTER (CREATIONAL-PATTERN) 12 3.2 Fabrik (Factory) Ein typisches Erzeugungsmuster in der objektorientierten Programmierung ist das Fabrik-Muster (Fac- tory Pattern). Anhand dieses Erzeugungsmusters lässt sich die Arbeitsweise exemplarisch für die ver- schiedenen Erzeugungsmuster gut beschreiben, so dass das Verständnis für die Arbeitsweisen und den Einsatz dieser Muster steigt. Eine Fabrik liefert typischerweise eine Instanz eines Objektes. Die Fabrik entscheidet meist anhand von Laufzeitdaten, welches konkrete Objekt instanziert werden soll und konfiguriert es gegebenenfalls. Der zum Teil recht komplexe Konstruktionsprozess wird durch die Fabrik gekapselt und vor anderen Objek- ten verborgen. Der Code der Klassen, welche die Fabrik nutzen, wird dadurch schlanker. Ein weiterer Vorteil liegt in der Wiederverwendbarkeit der Fabrik in einer ähnlichen Aufgabenstellung. Abbildung 2: UML Diagramm: für die Fabrik Betrachten wir eine simples konkretes Beispiel: Stellen wir uns ein Warensortiment eines Supermarktes vor. Artikel, die verkauft worden sind, werden softwaregesteuert nachbestellt, um die Regale wieder zu füllen. Dazu erhält das Modul „Einkauf“ eine Auflistung aller Artikel, die verkauft worden sind. Im folgenden Beispiel wird für jeden zu bestellenden Artikel ein passendes Objekt erzeugt. Abbildung 3: UML-Diagramm: für die Vererbungshierarchie des Beispiel zur Fabrik Wie das UML-Diagramm zeigt, wird das Warensortiment in verschiedene Kategorien unterteilt. Dies soll hier die Komplexität des Erzeugungsprozesses andeuten. Die Erzeugung der Instanzen in die Klasse „Einkauf“ zu integrieren würde diese Klasse sehr unhandlich werden lassen. Die Erzeugung der Instan- zen für die einzelnen Waren wird daher vor dem Rest des Programms in einer Fabrik versteckt. Diese Fabrik wird durch die Klasse „WarenFactory“ dargestellt und hat die Aufgabe, Instanzen von Waren zu Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 13 3.3 Quellcode: WarenFactory produzieren. In der Klasse „Einkauf“ reduziert sich die Erzeugung jeder beliebigen Ware auf den Aufruf der Methode „createProduct()“. Wie im Beispiel zu sehen ist, muss sich das Modul „Einkauf“ nicht näher um Details der Erzeugung einzelner Waren kümmern. Details sind in der Fabrik verborgen. 3.3 Quellcode: WarenFactory 1 class WarenFactory { 2 public Product createProduct ( String name) { 3 i f (name . equals ( " Plateau Schuh Lack" ) { 4 return new Schuh (39); 5 } 6 i f (name . equals ( "Banane" ){ 7 return new Obst ( "Banane" ) ; 8 } 9 . . . 10 } 11 public abstract class Product{ 12 / / Basisklasse fuer a l l e Produkite des Warensortiments 13 . . . 14 } 15 } 16 17 class Einkauf{ 18 public void bestelleWare ( String name) { 19 WarenFactory neueWare = new WarenFactory ( ) ; 20 / / Für a l l e Posten aus der Einkaufsliste : 21 neueWare . createProduct (name ) ; 22 / / verarbeite neueWare 23 } 24 } Eine Factory kann sinnvoll verwendet werden: • Wenn erst zur Laufzeit klar wird, welche konkreten Objekte erzeugt werden müssen. • Regeln zur Erzeugung von Objekten zusammengefasst werden sollen. Die Übersichtlichkeit wird dadurch erhöht. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 4 STRUKTURMUSTER (STRUCTURE PATTERN) 14 4 Strukturmuster (Structure Pattern) Strukturmuster befassen sich mit der Komposition von Klassen und Objekten, um größere Strukturen zu schaffen. Aus den zahlreichen Mustern, die von GoF aufgeführt sind, wählen wir an dieser Stelle den Adapter, die Fassade und das Kompositum aus. Alle drei Entwurfsmuster finden zahlreich Anwendung. Dabei sind die Motivationen für den Adapter und die Fassade leicht verständlich und machen gut die grundlegende Idee von Strukturmustern klar. Das Kompositum ist ein etwas schwerer verständliches Kenzept. Dessen Eleganz macht das Nachdenken darüber aber lohnenswert. 4.1 Strukturmuster nach GoF Nach GoF gibt es folgende Strukturmuster: • Adapter (Adapter) • Brücke (Bridge) • Dekorierer (Decorator) • Fassade (Facade) • Fliegengewicht (Flyweight) • Komposition (Composite) • Proxy (Proxy) • Klassenbassierte Strukturmuster benutzen Vererbung, um Schnittstellen oder Implementierun- gen zusammenzuführen (wie z.B. Mehrfachvererbung, durch die zwei oder mehr Klassen zu einer einzigen zusammengeführt werden) • Objektbasierte Stukturmuster beschreiben Mittel und Wege, Objekte zusammenzuführen, um neue Funktionalität zu gewinnen. Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 15 4.2 Adapter (Adapter) 4.2 Adapter (Adapter) Das Muster Adapter übersetzt Schnittstellen zweier Komponenten ineinander - in Analogie zu einem Stromadapter, der zwischen eine ausländische Steckdose und einem heimischen elektrischen Gerät ge- schaltet wird. Wird Software modular aus wieder verwendeten Komponenten zusammengesetzt und sind die Komponenten sauber mit klaren Schnittstellen programmiert, heißt das noch lange nicht, dass ver- schiedene Komponenten direkt miteinander kommunizieren können. Oft ist Übersetzungsarbeit notwen- dig, die die Ausgaben einer Komponente in Eingaben für die andere Komponente wandelt und umge- kehrt. Im Sinne einer objektorientierten Modularisierung ist es nicht sinnvoll, die Schnittstellen der be- teiligten Komponenten zu modifizieren. Eine bessere Lösung ist es, zwischen beide Komponenten einen Adapter zu platzieren, der die Kommunikation zwischen beiden Komponenten regelt. Die Komponen- ten greifen dann nicht mehr direkt aufeinander zu, sondern indirekt über den Adapter, der die Anfragen übersetzt und weiterleitet. Abbildung 4: Adapter Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 4 STRUKTURMUSTER (STRUCTURE PATTERN) 16 4.3 Fassade (Facade) Dem Muster Adapter ist das Muster Fassade ähnlich. Hier ist die Idee, den Zugriff auf eine fertige Kom- ponente, die eine komplexe Schnittstelle bietet, zu vereinfachen. Vor die vorhandene Schnittstelle wird eine vereinfachte Schnittstelle gestellt, die nur die Funktionalitäten enthält, die gebraucht werden. Die nicht benötigten Funktionalitäten sind nicht mehr sichtbar. Auf diese Weise können allgemein gehaltene Schnittstellen für einen konkreten Anwendungsfall spezifiziert werden ohne die originale Schnittstelle modifizieren zu müssen. Aufrufe erfolgen nur noch über die vorgelagerte Schnittstelle, die so genannte Fassade. Die Fassade übersetzt die vereinfachten Anfragen von aussen und bedient intern die komplexe- ren Schnittstellen der von ihr verborgenen Komponente. Benutzern der Komponente fällt es mittels einer Fassade leichter, die Funktionalität zu finden, die sie brauchen. Abbildung 5: Fassade Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 17 4.4 Kompositum (Compositum, Container) 4.4 Kompositum (Compositum, Container) Das Strukturmuster Kompositum bzw. Container (engl. Composite, Container) wird angewendet, um Teile-Ganzes-Hierarchien zu repräsentieren. Die Grundidee des Kompositionsmusters ist es, in einer abstrakten Klasse sowohl primitive Objekte also auch ihre Behälter zu repräsentieren. Somit können sowohl einzelne Objekte, also auch ihre Kompositionen einheitlich behandelt werden. Abbildung 6: UML-Diagramm: für die Kompositum Um die Vorteile dieses auf den ersten Blick komplizierten aber eleganten Konzeptes zu verstehen, wen- den wir uns wieder einem konkreten Beispiel zu: Grafische Benutzeroberflächen können in Java mittels Swing erzeugt werden. Benutzeroberflächen ent- halten typische Elemente wie Beschriftungen (JLabel), Knöpfe (JButton), weitere Zeichenflächen (JPa- nel) usw. Abbildung 7: Vererbungshierarchie für Beispiel zur Komposition Ein Blick auf die Vererbungshierarchie zeigt, dass JFrame, JButton, JPanel und JLabel abgeleitet sind von einer Klasse mit dem Namen Container und somit wegen Polymorphie alle selbst Container sind. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 4 STRUKTURMUSTER (STRUCTURE PATTERN) 18 Die Klasse Container enthält die zwei für diese Betrachtung interessanten Methoden add(Container) und print(Graphics). Die Methode add(Container) fügt dem Container einen weiteren Container hinzu und die Methode print(Graphics) zeichnet den Container. Im Beispielcode wird ein leeres Fenster (JFrame) erzeugt (Zeile 5). Da das Fenster ein Container ist, können dem Fenster andere Container hinzugefügt werden, zum Beispiel Beschriftungen (Klasse JLabel, Zeile 19) oder auch weitere Zeichenflächen (JPanel, Zeile 12, 17), die selbst wiederum Container sind und weitere Elemente beinhalten. In diesem Beispiel beinhaltet das JPanel noch einen Knopf (JButton, Zeile 14). Wirft man nun einen Blick in die Sourcen der SUN-Api, und zwar in die Methode print(Graphics) der Klasse Component (eigentlich in die Methode paint(Graphics), die von print(Graphics) aufgerufen wird), so zeigen sich nur wenige Zeilen, um jede Komponente zu zeichnen: Die Komponente zeichnet sich selbst und ruft für alle im Container enthaltenen Elemente, welche ja wiederum selbst Container sind, die Methode print(Graphics) auf. Der Container muss also nicht wissen, wie die in ihm enthaltenen Container darzustellen sind. Man führe sich die Mächtigkeit und Eleganz dieses Konzeptes an dieser Stelle noch einmal deutlich vor Augen: Unabhängig davon, ob ein Fenster gezeichnet werden soll oder nur ein einzelner Knopf - immer wieder wird ein und dieselbe kurze Methode aufgerufen, die rekursiv alle Container durchläuft und die ganze Zeichenarbeit erledigt. Von außen ist also nicht ersichtlich, ob es sich um eine einzelne Komponente handelt oder um eine komplexe Zusammensetzung diverser Komponenten. Beide Fälle können vom Aufrufer gleich behandelt werden. Ein Aufrufer kann also einheitlich mit diesen rekursiv geschachtelten Strukturen umgehen. Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 19 4.5 Quellcode: Container 4.5 Quellcode: Container 1 / / imports . . . 2 public class Beispiel_Fuer_Container { 3 public s t a t i c void main( String [] args ) { 4 / / Neues Fenster erzeugen 5 JFrame fenster = new JFrame ( ) ; 6 / / Auf die Zeichenflaeche zeichnen 7 Container zeichenflaeche = fenster . getContentPane ( ) ; 8 / / Layout setzen 9 zeichenflaeche . setLayout (new BorderLayout ( ) ) ; 10 11 / / Einen neuen Container erzeugen 12 JPanel panel = new JPanel ( ) ; 13 / / Dem neuen Container einen Button hinzufügen 14 panel . add (new JButton ( " Click me" ) ) ; 15 16 / / Dem Fenster den Container panel hinzufügen 17 zeichenflaeche . add ( panel , BorderLayout .SOUTH) ; 18 / / Dem Fenster eine Beschriftung hinzufügen 19 zeichenflaeche . add (new JLabel ( "Lebe immer f i r s t class , sonst tun es Deine Erben" ) , 20 BorderLayout .NORTH) ; 21 22 / / Größe des Fensters optimieren 23 fenster . pack ( ) ; 24 / / Fenster anzeigen 25 fenster . setVisible ( true ) ; 26 } 27 } Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 5 VERHALTENSMUSTER (BEHAVIOR PATTERN) 20 5 Verhaltensmuster (Behavior Pattern) Verhaltensmuster befassen sich mit Algorithmen und der Zuweisung von Zuständigkeiten zu Objekten. Wieder greifen wir hier exemplarisch einige Entwurfsmuster auf: Der Beobachter ist ein weit verbreitetes Konzept. Ein Verständnis dieses Musters ist daher an vielen Stellen hilfreich. Model - View - Controller (MVC) ist Muster, das nicht durch GoF aufgelistet wurde, dem Observer aber ähnelt und im Softwaredesign eine herausragende Rolle spielt. Wir listen es daher an dieser Stelle. Die Strategie ist ein einfach zu verstehendes Entwurfsmuster, welches es ermöglicht, Algorithmen zur Laufzeit auszutauschen. Die Strategie macht gut die gemeinsame Idee der Verhaltensmuster klar. 5.1 Verhaltensmuster nach GoF Nach GoF gibt es folgende Verhaltensmuster: • Befehl (Command) • Beobachter (Observer) • Besucher (Visitor) • Interpreter (Interpreter) • Iterator (Iterator) • Memento (Memento) • Schablonenmethode (Template Method) • Strategie (Strategy) • Vermittler (Mediator) • Zustand (State) • Zuständigkeitskette (Chain of Responsibility) • Model View Controller (MVC) • Klassenbasierte Verhaltensmuster verwenden Vererbung, um das Verhalten unter den Klassen zu verteilen • Objektbasierte Verhaltensmuster verwenden Objektkomposition anstelle von Vererbung Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 21 5.2 Beobachter (Observer) 5.2 Beobachter (Observer) Das Entwurfsmuster Beobachter wird zahlreich in der JAVA-API von SUN eingesetzt und daher dem interessierten JAVA-Programmierer immer wieder begegnen, beispielsweise bei der Entwicklung von grafischen Oberflächen (GUI). Auch bekannt ist dieses Muster unter dem Namen „Listener“. Oft ist die Problemstellung, Objekte die miteinander in Beziehung stehen, in einem konsistenten Zu- stand zu halten. Ändert sich ein Objekt, müssen sich abhängige Objekte aktualisieren. Die dabei rele- vante Fragestellung ist, wie der Abgleich zwischen allen beteiligten Objekten stattfindet, ohne zu große Abhängigkeiten zu schaffen. Das Muster Beobachter setzt sich aus zwei Teilen zusammen: 1. Einem Objekt, das beobachtet wird (Subjekt), 2. Einer Liste von Objekten, die dieses beobachten (Beobachter). Sind Beobachter an den Änderungen eines Subjektes interessiert, melden sie sich beim Subjekt an. Das Subjekt stellt dafür die Methode „MeldeBeobachterAn()“ bereit. Viele Beobachter können sich am Sub- jekt anmelden. Ändert sich das Subjekt, benachrichtigt es all seine Beobachter. Dies geschieht durch Aufruf der Metho- de „Aktualisiere()“. Jeder Beobachter hat diese Methode implementiert. Dies wird garantiert durch das Interface „Beobachter“, welches eine Implementierung der Methode „Aktualisiere()“ verlangt. Jeder Beobachter beschreibt also die Aktionen selbst, die bei Änderungen des Subjektes durchgeführt werden sollen. Angestoßen werden diese Aktionen vom Subjekt, wann immer es sich ändert durch Auf- ruf der Methode „Benachrichtige()“. Ist ein Beobachter nicht mehr interessiert an Änderungen des Sub- jekts, ruft er die Methode „MeldeBeobachterAb()“ auf. Entwurfsmuster werden unabhängig von einer Programmiersprache beschrieben. In konkreten Program- miersprachen kann die Realisierung von dieser Beschreibung leicht abweichen. In Java wird ein Subjekt durch Ableitung von der Klasse „Observable“ erzeugt. Die Basisklasse „Observable“ stellt die Metho- den „notifyObservers()“, „addObserver(Observer)“ und „deleteObserver(Observer)“ schon fertig bereit. Ein Beobachter muss das Interface „Observer“ implementieren, d.h. die Methode „update(Observable, Object)“ konkretisieren. Abbildung 8: UML-Diagramm: Beobachter Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 5 VERHALTENSMUSTER (BEHAVIOR PATTERN) 22 Um dieses Konzept zu verdeutlichen, stellen wir uns eine Party mit einer netten Gesellschaft vor. Hier fin- den sich zurückhaltende Gäste und aktive Erzähler. Die Zuhörer sind interessiert an den Gesprächen der Unterhalter (Subjekte). Die Erzähler - hier sogar Witzeerzähler - sind also die Beobachteten (Observa- ble). Die Zuhörer sind die Beobachter (Observer). Sie scharen sich um die Erzähler, die sie interessieren, um ihnen zuzuhören. 5.3 Quellcode Beispiel - Beobachter 1 / / Observable − Klasse der JAVA−API vererbt die Methoden : 2 / / addObserver ( Observer ) − fügt einen Zuhörer hinzu 3 / / deleteObserver ( Observer ) − löscht einen Zuhörer 4 / / notifyObservers ( Observer ) − benachrichtigt a l l e r e g i s t r i e r t e n Zuhörer 5 / / durch Aufruf der Methode update ( . . . ) 6 class Witzeerzaehler extends Observable { 7 public void erzaehleWitz ( String witz ) { 8 notifyObservers ( witz ) ; 9 / / r u f t die Methode update ( . . . ) von allen angemeldeten Beobachtern auf 10 } 11 } 12 13 / / Observer − Interface der JAVA−API 14 / / Zu implementieren i s t die Methode update ( Observable , Object ) 15 class Zuhoerer implements Observer { 16 private String name; 17 Zuhoerer ( String name) { 18 t h i s . name = name; 19 } 20 public void update ( Observable o , Object obj ) { 21 System . out . println (name + " lacht über " + obj ) ; 22 } 23 } 24 25 / / Main 26 class Party { 27 public s t a t i c void main ( String args [ ] ) { 28 Zuhoerer jan = new Zuhoerer ( " Jan" ) ; 29 Zuhoerer bob = new Zuhoerer ( "Bob" ) ; 30 Witzeerzaehler carsten = new Witzeerzaehler ( " Carsten " ) ; 31 carsten . addObserver ( jan ) ; 32 carsten . addObserver (bob ) ; 33 carsten . erzaehleWitz ( "There are only 10 kind of person " + 34 "who can read binaries . . . " ) ; 35 carsten . deleteObserver ( jan ) ; 36 carsten . erzaehleWitz ( "Eine Null kann ein bestehendes Problem verzehnfachen . " ) ; 37 carsten . deleteObserver (bob ) ; 38 carsten . erzaehleWitz ( "How many people can read hex , i f " + 39 " only you and dead people can? (Lsg . : deae ) " ) ; 40 } 41 } Ausgabe: Jan lacht über „There are only 10 kind of person who can read binaries ...“ Bob lacht über „There are only 10 kind of person who can read binaries ...“ Bob lacht über „Eine Null kann ein bestehendes Problem verzehnfachen.“ Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 23 5.3 Quellcode Beispiel - Beobachter Betrachten wir den Quellcode im Detail: In Zeile 28 und 29 werden die zwei Zuhörer „Jan“ und „Bob“ instanziert. In Zeile 30 wird ein neuer Wit- zeerzähler „Carsten“ ins Leben gerufen. Durch Zeile 31 und 32 drücken die beiden Zuhörer ihr Interesse an Carstens Witzen aus. In Zeile 33 legt der Witzeerzähler los: Die Methode „erzaehleWitz(String)“ ruft durch die Methode „notifyObservers()“ (Zeile 8) die Methode „update(...)“ (Zeile 20) von allen ange- meldeten Zuhörern auf. In diesem Fall werden also Jan und Bob benachrichtigt. Die Methode „update()“ gibt einfach das übergebene Objekt - hier ein String - auf dem Bildschirm aus (Zeile 21). Der erste Witz wird also zwei Mal gehört. Jan meldet sich anschließend von Carsten ab (Zeile 35), so dass nur noch Bob zuhört. Dieser hört dann den zweiten Witz (Zeile 36). Bob verabschiedet sich nun auch (Zeile 37), so dass der dritte Witz (Zeile 38) von keinem mehr vernommen wird. Lassen Sie das Konzept nochmals auf sich wirken: Beobachter können sich am Subjekt an- und abmelden und werden durch den Aufruf einer Methode benachrichtigt, wenn sich das Subjekt ändert. Die Kopplung zwischen Subjekt und Beobachter ist minimal. Subjekt und Beobachter bleiben voneinander unabhängig. Dennoch funktioniert die Kommunikation zwischen allen beteiligten Objekten wie gewünscht. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 5 VERHALTENSMUSTER (BEHAVIOR PATTERN) 24 5.4 Model View Controller (MVC) Model-View-Controller (MVC) ist ein Konzept, das aus der objektorientierten Sprache Smalltalk stammt und in vielen Bereichen moderner Softwareentwicklung eingesetzt wird. Es findet beispielsweise seinen Einsatz häufig in grafischen Benutzeroberflächen, so auch in der Swing-Bibliothek von Java. Die Idee des Musters ist die Trennung eines Programms in die drei Einheiten Datenmodell (Model), Präsentation (View) und Programmsteuerung (Controller). Ziel des Modells ist ein flexibles Programmdesign. Eine der drei Einheiten kann leicht modifiziert oder ausgetauscht werden ohne dass die anderen zwei Einhei- ten davon betroffen sind. Weiterhin sorgt der MVC-Ansatz für eine gewisse Übersicht und Ordnung in großen Anwendungen. Die Trennung bringt eine Rollenverteilung mit sich. Spezialisten können für die einzelnen Teilaufgaben eingesetzt werden: Web-Designer entwerfen das Erscheinungsbild, Programmie- rer erstellen die nötige Geschäftslogik, Datenbankexperten kümmern sich um die optimale Datenverwal- tung. Folgendes Schaubild zeigt die Aufteilung eines Softwaresystems in die drei Komponenten Model - View - Controller grafisch. Abbildung 9: Model View Controller Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 25 5.4 Model View Controller (MVC) 5.4.1 Model Das Datenmodell enthält die dauerhaften (persistenten) Daten der Anwendung. Das Model hat also Zu- griff auf diverse Backend-Speicher wie zum Beispiel Datenbanken. Das Model kennt weder die View noch den Controller, es weiß also nicht, wie, ob und wie oft es dargestellt und verändert wird. Ände- rungen im Model werden über einen Update-Mechanismus bekannt gegeben, indem ein Event ausgelöst wird. 5.4.2 View Die Darstellungsschicht präsentiert die Daten. Sie enthält keine Programmlogik. Die View kennt das Model und ist dort registriert, um sich selbständig aktualisieren zu können. Wie die Daten dargestellt werden, wird nur vom View bestimmt, nicht vom Model. Auch ist es möglich, mehrere Views auf dem gleichen Model basieren zu lassen. 5.4.3 Controller Der Controller - auch Steuerungsschicht genannt - realisiert die eigentliche Geschäftsintelligenz. Er steu- ert den Ablauf, verarbeitet Daten, entscheidet, welche View aufgerufen wird, etc. Der Controller küm- mert sich um die Interaktion mit dem Benutzer. Wird beispielsweise in einer angezeigten Tabelle ein Wert geändert, so teilt der Controller dies dem Model mit, welches wiederum die View darüber informiert - der neue Wert wird angezeigt. Der Controller ist also die Logik der Anwendung. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 5 VERHALTENSMUSTER (BEHAVIOR PATTERN) 26 5.4.4 MVC - Darstellung Abbildung 10: Model View Controller Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 27 5.5 Model View Controller in JAVA Swing 5.5 Model View Controller in JAVA Swing Betrachten wir noch beispielhaft den Einsatz von MVC in der Java-API. Bei Swing werden die View und der Controller zusammengefasst als so genanntes UI Delegate. Die Klasse javax.swing.plaf.ComponentUI besitzt dazu Unterklassen für die unterschiedlichen Oberflächen- elemente. Diese Klasse kümmert sich neben dem Aussehen um das Verhalten der Oberfläche, so dass beispielsweise Windows-typische Tastenkürzel beim Windows-Look-and-Feel die gleiche Reaktion her- vorrufen. Viele Swing-Komponenten besitzen ein oder mehrere Models, die der Programmierer erweitern kann. Eine typische Aufgabenstellung ist hierbei die Anbindung einer Datenbank für die Lieferung der Daten. Zu diesem Zweck besitzen alle Datenmodelle eine Methode, um die Anzahl der Daten zu bekommen und eine Methode, um ein bestimmtes Datum (z.B. über eine Indexangabe) zu liefern. Zudem ist allen Models gemeinsam, dass die Hauptkomponente sich bei dem Model als Listener regi- striert. Damit hat das Model die Möglichkeit, bei Veränderung die Komponente darüber zu benachrich- tigen. Die Komponente wird dann dazu passend die Oberfläche neu zeichnen und die benötigten Daten aus dem Model holen. Neben der reinen Datenquelle kann ein Modell auch manipulierte Daten liefern. Dies könnte beispiels- weise durch eine Sortierung oder ein Ausblenden von bestimmten Daten geschehen. Als Beispiel soll ein ComboBoxModel dienen, bei denen man eine Auswahl der Daten über einen Such- string vornehmen kann. Wenn hier die Methode setSearchString(String searchString) aufgerufen wird, soll das Model nur die Datenelemente zeigen, die mit diesem String anfangen. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 5 VERHALTENSMUSTER (BEHAVIOR PATTERN) 28 5.6 Quellcode: für Java Swing - SuchStringComboBoxModel 1 class SuchstringComboBoxModel extends DefaultComboBoxModel { 2 / / Suchstring , mit dem a l l e 3 / / Elemente anfangen müssen 4 private String searchString = "" ; 5 6 /∗∗ 7 ∗ Konstruktor 8 ∗/ 9 public SearchStringComboBoxModel ( String [] textStrings ) { 10 / / String−Array wird in der 11 / / geerbten Klasse gespeichert 12 super ( textStrings ) ; 13 } 14 15 public void setSearchString ( String searchString ) { 16 t h i s . searchString = searchString ; 17 / / Die ComboBox benachrichtigen , 18 / / dass sich die Daten komplett geändert haben 19 fireContentsChanged ( this , 0 , getSize ( ) ) ; 20 } 21 22 /∗∗ 23 ∗ Liefert die Anzahl der Werte , die mit 24 ∗ suchString anfangen 25 ∗/ 26 public int getSize () { 27 int size = 0; 28 for ( int i = 0; i < super . getSize ( ) ; i ++) 29 i f ( super . getElementAt ( i ) . toString ( ) . 30 startsWith ( searchString )) 31 ++size ; 32 return size ; 33 } 34 35 /∗∗ 36 ∗ Liefert das Element mit dem angegebenen 37 ∗ Index aus der Menge der Elemente , die 38 ∗ mit searchString anfangen 39 ∗/ 40 public Object getElementAt ( int index ) { 41 for ( int i = 0; i < super . getSize ( ) ; i ++) 42 i f ( super . getElementAt ( i ) . toString ( ) . 43 startsWith ( searchString )) 44 i f ( index−− == 0) 45 return super . getElementAt ( i ) ; 46 return null ; 47 } 48 } Die Benachrichtigung über die Änderungen sollte möglichst nur die Daten betreffen, die sich wirklich geändert haben. Zu diesem Zweck gibt es in den meisten Models Methoden, die beispielsweise den Bereich angeben, in der sich geänderte Daten befinden. Dadurch kann die Oberfläche selbst entscheiden, ob sie neu gezeichnet werden muss oder nicht. Dies steigert in vielen Fällen die Performance (z.B. bei großen Tabellen). Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 29 5.7 Strategie (Policy) 5.7 Strategie (Policy) Ein weiteres Verhaltensmuster ist die Strategie. Dieses Muster wird benutzt, um Algorithmen zu kapseln, die austauschbar sein sollen. Die Komponente, die den Algorithmus nutzt wird von dem Algorithmus selbst entkoppelt. Der Algorithmus wird dadurch zur Laufzeit austauschbar und die aufrufende Kompo- nente schlanker, d.h. besser les- und wartbar. Von Vorteil ist dies, wenn abhängig von Laufzeitbedingun- gen ein Algorithmus aus einem Pool von Algorithmen ausgesucht werden kann. Jeder Algorithmus hat dabei eine einheitliche Schnittstelle, hinter der er seine Funktionalität verbirgt. Der Aufruf von außen erfolgt dabei immer in der gleichen Art und Weise. Abbildung 11: UML-Diagramm: für Strategie Als konkretes Beispiel sei das Look & Feel einer grafischen Oberfläche genannt. Unter dem Betriebssy- stem Windows ist es möglich, die Darstellung von Fenstern zu verändern. Die Komponente, die für das Zeichnen dieser grafischen Elemente zuständig ist, wird dabei ausgetauscht, ohne dass andere Program- me, die die austauschbare Komponente nutzen von der Änderung betroffen sind. Ein solcher Designansatz hilft auch bei einer Portierung von Software auf ein anderes Betriebssystem: Wenn verarbeitender Code und Darstellung von GUI-Elementen nicht verwoben sind, ist es leichter, die Darstellung von GUI-Elementen durch eine andere vom Betriebssystem bereit gestellte Bibliothek zu ersetzen. Abbildung 12: UML-Diagramm: Einsatz einer Strategie für GUI Als ein anderes einleuchtendes Beispiel soll ein Steuerprogramm dienen, das die Berechnung von Steu- ersätzen möglichst in Strategie-Objekte auslagern sollte, um einfach länderabhängig konfigurierbar zu sein. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 6 WEITERE MUSTER 30 6 Weitere Muster GoF haben mit dem Erscheinen Ihres Werkes „Design Pattern Elements of Reusable Object-Oriented Software“ im Jahre 1995 zu einer breiten Akzeptanz von Entwurfsmustern beigetragen. Der von den Autoren in diesem Werk zusammengestellte Musterkatalog wird nach wie vor als zentrales Werk in der Entwurfsmusterszene angesehen, dennoch deckt es nur einen kleinen Bereich ab. Es gibt viele weitere Entwurfsmuster, die weitere bewährte Lösungen für andere Themenfelder beschreiben: • So gibt es einen Musterkatalog für die Enterpriseversion von Java (J2EE) von SUN, die bewährte Entwürfe und Architekturen erfassen und nutzbar machen. Diese Muster beziehen sich auf Serv- lets, Java Server Pages (JSP), Enterprise Java Beans (EJB) und Java Message Service (JMS). • Architekturmuster bieten eine sehr umfassende Sicht auf Softwarearchitekturen, wie z.B. „Client Server“, „n-Tier“oder „4 Layer Architecture“ • Im Umgang mit Datenbanken, XML, Kommunikation über Netzwerke, verteilten Anwendungen und weiteren Fachgebieten sind jeweils Muster entstanden bzw. zusammengetragen worden. Da es sich eher um ein Sammeln und Notieren von vorhandenen guten Lösungen handelt, spricht man in diesem Zusammenhang auch von „pattern mining“, also dem Schürfen nach Mustern. Die Idee der Entwurfsmuster verbreitet sich wie diese Auflistung zeigt in alle Bereiche der Softwareentwicklung. Viele Software-Ingenieure überall auf der Welt dokumentieren ihre Erfahrung mit Mustern. Es existieren bereits eine Menge von Mustern in jeder Größenordnung, auf jedem Abstraktionsniveau und für viele Anwendungsgebiete. Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 31 7 VOR- UND NACHTEILE VON ENTWURFSMUSTERN 7 Vor- und Nachteile von Entwurfsmustern Die Sinnhaftigkeit von Entwurfsmustern ergibt sich aus der konkreten Problemstellung. Wir listen hier einige Kriterien auf, die helfen können, sich für oder gegen den Einsatz von Entwurfsmustern zu ent- scheiden: NACHTEILE: • Das Design zur Entwurfs- bzw. Konzeptionszeit ist sehr aufwendig. • Es gibt viele Muster - Eine Reduktion auf das Wesentliche ist notwendig. • Muster werden im Netzwerk schnell sehr komplex. • Quellcode mit Entwurfsmustern ist schwer zu debuggen. • Muster sind ohne eine grafische Visualisierung (UML) schwer zu erkennen. Im reinen Code ist dies fast unmöglich. • Der Einarbeitungsaufwand in die Ideen der Entwurfsmuster ist hoch. VORTEILE: • Der Entwicklungsprozess wird standardisierter. • Die Kommunikation zwischen Entwicklern wird verbessert - Diskussion über Softwaredesign wird auf abstrakter Ebene möglich. • Die Systemanalyse wird erleichtert. • Die Idee eines Entwurfs ist in Mustern erkennbar. • Muster sind sehr effiziente Lösungen. • Muster realisieren die Vorteile der objektorientierten Programmierung. • Die Wartbarkeit des Codes ist schnell und einfach. • Änderungen an der Software sind schnell und einfach durchführbar. • Die Wiederverwendbarkeit des Codes steigt deutlich an. • Der Code wird robuster, weil bewährte Lösungen verwendet werden. • Der Code wird kompakt. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 8 SCHLUSSBEMERKUNG 32 8 Schlussbemerkung Entwurfsmuster sind Ideenlieferanten. Entwurfsmuster bieten keine neuen programmiertechnischen Möglichkeiten, sondern eine Sammlung von bewährten Lösungen für immer wiederkehrende Problem- stellungen der Softwareentwicklung in abstrahierter Form. Die Einarbeitung ist schwer, weil ein neuer Blick auf die Problemanalyse von zu erstellender Software gefordert wird und viel Wissen über objekt- orientierte Programmierung vorausgesetzt wird. Viele Entwurfsmuster sind anfangs schwer verständlich und der Sinn nicht ersichtlich. Dennoch lohnt sich unserer Meinung nach die Beschäftigung mit dem Thema: Ihre Sicht auf die Softwareentwicklung wird sich verändern. Nach einiger Zeit lässt sich in der täglichen Arbeit mehr und mehr entdecken, dass bestimmte Probleme mit Entwurfsmustern elegant gelöst werden können und damit ein flexibleres Design erreicht wird, als es ohne Entwurfsmuster möglich wäre. Proble- me können mit einem größeren Blick erfasst und analysiert werden und deren Lösungen genügen einem guten objektorientierten Design: Austauschbare, miteinander interagierende Softwarebausteine erhöhen die Lesbarkeit, Wartbarkeit und die Robustheit von Code und führen damit zu einer besseren Software- lösung. Durch die Auflistung von Entwurfsmustern wurde die Möglichkeit geschaffen, Erfahrungswissen von er- fahrenen Programmieren zugänglich zu machen. Die Beschäftigung mit Entwurfsmustern ist eine schnel- le Möglichkeit, sich praxiserprobtes Entwicklerwissen anzueignen, das sich sonst erst durch jahrelange Praxis anhäuft. Das Thema ist daher - nach einem etwas zähen Einstieg - für Programmierfans ein echter Leckerbissen. Wohl bekomm´s ! Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 33 9 MUSTERKATALOG 9 Musterkatalog Es gibt eine solche Vielzahl von Mustern in der Software-Technik, dass hier nur die Muster nach GoF vorgestellt werden. Wir übernehmen an dieser Stelle die Definitionen und Beschreibungen von GoF. 9.1 Erzeugungsmuster • Abstrakte Fabrik Biete eine Schnittstelle zum Erzeugen von Familien verwandter oder voneinander abhängiger Ob- jekte, ohne ihre konkreten Klassen zu benennen. • Erbauer Trenne die Konstruktion eines komplexen Objekts von seiner Repräsentation, so dass derselbe Konstruktionsprozess unterschiedliche Repräsentationen erzeugen kann. • Fabrikmethode Definiere eine Klassenschnittstelle mit Operationen zum Erzeugen eines Objekts, aber lasse Un- terklassen unterscheiden, von welcher Klasse das zu erzeugende Objekt ist. Fabrikmethoden er- möglichen es einer Klasse, die Erzeugung von Objekten an Unterklassen zu delegieren. • Prototyp Bestimme die Arten zu erzeugender Objekte durch die Verwendung eines prototypischen Exem- plars, und erzeuge neue Objekte durch Kopieren dieses Prototypen. • Singleton Sichere ab, dass eine Klasse genau ein Exemplar besitzt, und stelle einen globalen Zugriffspunkt darauf bereit. 9.2 Strukturmuster • Adapter Passe die Schnittstelle einer Klasse an eine andere von ihren Klienten erwartete Schnittstelle an. Das Adaptermuster lässt Klassen zusammenarbeiten, die wegen inkompatibler Schnittstellen an- sonsten dazu nicht in der Lage wären. • Brücke Entkopple eine Abstraktion von ihrer Implementierung, so dass beide unabhängig voneinder vari- iert werden können. • Dekorierer Erweitere ein Objekt dynamisch um Zuständigkeiten. Dekorierer bieten eine flexible Alternative zur Unterklassenbildung, um die Funktionalität einer Klasse zu erweitern. • Fassade Biete eine einheitliche Schnittstelle zu einer Menge von Schnittstellen eines Subsystems. Die Fas- sendenklasse definiert eine abstrakte Schnittstelle, welche die Verwendung des Subsystems ver- einfacht. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 9 MUSTERKATALOG 34 • Fliegengewicht Nutze Objekte kleinster Granularität gemeinsam, um große Mengen von ihnen effizient verwenden zu können. • Kompositum Füge Objekte zu Baumstrukturen zusammen, um Teil-Ganzes-Hierarchien zu repräsentieren. Das Kompositionsmuster ermöglicht es Klienten, einzelne Objekte sowie Kompositionen von Objekten einheitlich zu behandeln. • Proxy Kontrolliere den Zugriff auf ein Objekt mit Hilfe eines vorgelagerten Stellvertreterobjekts. 9.3 Verhaltensmuster • Befehl Kapsle einen Befehl als ein Objekt. Dies ermöglicht es, Klienten mit verschiedenen Anfragen zu parametrisieren, Operationen in eine Schlange zu stellen, ein Logbuch zu führen und Operationen rückgängig zu machen. • Beobachter Definiere eine 1-zu-n Abhängigkeit zwischen Objekten, so dass die Änderung des Zustands ei- nes Objekts dazu führt, dass alle abhängigen Objekts benachrichtigt und automatisch aktualisiert werden. • Besucher Kapsle eine auf den Elementen einer Objektstruktur auszuführende Operationen als ein Objekt. Das Besuchermuster ermöglicht es Ihnen, eine neue Operation zu definieren, ohne die Klassen der von ihr bearbeiteten Elemente zu verändern. • Interpreter Definiere für eine gegebene Sprache eine Repräsentation der Grammatik sowie einen Interpreter, der die Repräsentation nutzt, um Sätze in der Sprache zu interpretieren. • Memento Erfasse und externalisiere den internen Zustand eines Objekts, ohne seine Kapselung zu verletzen, so dass das Objekt später in diesen Zustand zurückversetzt werden kann. • Schablonenmethode Definiere das Skelett eines Algorithmus in einer Operation und delegiere einzelne Schritte an Unterklassen. Die Verwendung einer Schablonenmethode ermöglicht es Unterklassen, bestimmte Schritte eines Algorithmus zu überschreiben, ohne seine Struktur zu verändern. • Strategie Definiere eine Familie von Algorithmen, kapsele jeden einzelnen und mache sie austauschbar. Das Strategiemuster ermöglicht es, den Algorithmus unabhängig von ihn nutzenden Klienten zu variieren. • Vermittler Definiere ein Objekt, welches das Zusammenspiel einer Menge von Objekten in sich kapselt. Ver- mittler fördern lose Kopplung, indem sie Objekte davon abhalten, aufeinander explizit Bezug zu Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 35 9.3 Verhaltensmuster nehmen. Sie ermöglichen es Ihnen, das Zusammenspiel der Objekte von ihnen unabhängig zu variieren. • Zustand Ermögliche es einem Objekt, sein Verhalten zu ändern, wenn sein interner Zustand sich ändert. Es wird so aussehen, als ob das Objekt seine Klasse gewechselt hat. • Zuständigkeitskette Vermeide die Kopplung des Auslösers einer Anfrage an seinen Empfänger, indem mehr als ein Objekt die Möglichkeit erhält, die Anfrage zu erledigen. Verkette die empfangenden Objekte, und leite die Anfrage an der Kette entlang, bis ein Objekt sie erledigt. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • ABBILDUNGSVERZEICHNIS 36 10 Abbildungsverzeichnis Abbildungsverzeichnis 1 Organisation des Katalogs der Entwurfsmuster nach GoF . . . . . . . . . . . . . . . . 10 2 UML Diagramm: für die Fabrik . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12 3 UML-Diagramm: für die Vererbungshierarchie des Beispiel zur Fabrik . . . . . . . . . 12 4 Adapter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 15 5 Fassade . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 16 6 UML-Diagramm: für die Kompositum . . . . . . . . . . . . . . . . . . . . . . . . . . 17 7 Vererbungshierarchie für Beispiel zur Komposition . . . . . . . . . . . . . . . . . . . 17 8 UML-Diagramm: Beobachter . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21 9 Model View Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 24 10 Model View Controller . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26 11 UML-Diagramm: für Strategie . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29 12 UML-Diagramm: Einsatz einer Strategie für GUI . . . . . . . . . . . . . . . . . . . . 29 13 Beispiel: Klassendiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 40 14 Beispiel: Objektdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41 15 Beispiel Interaktionsdiagramm . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 42 Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 37 LITERATUR Literatur [1] ADAMS, DOUGLAS: The Hitchhikers Guide to the Galaxy. BBC Press, 1979. [2] ALEXANDER, CHRISTOPHER: The Timeless Way of Building. Oxford University Press, 1979. [3] ALEXANDER, CHRISTOPHER, SARA ISHIKAWA, MURRY SILVERSTEIN, MAX JOHNSON, INGRIED FIKSDAHL-KING und SHLOMO ANGEL: A Pattern Language. Oxford University Press, New York, 1977. [4] BROWN, W.J., H.W. MCCORMICK, S.W. THOMAS und T.J. MOWBRAY: Antipatterns: Refactoring Software, Architecture, and Projects in Crisis. John Wiley and Sons, 1998. [5] BUSCHMANN, F., R. MEUNIER, H. ROHNERT, P. SOMMERLAD und M. STAL: Pattern-orientierte Software-Architektur: Ein Pattern-System. Addiosn-Wesley, 1988. [6] COPLIEN, J.O.: Software Patterns. SIGS Books, New York, 1996. [7] COPLIEN, J.O.: The Column Without a Name: Pattern Languages, C++ Report, Vol.9, No.1. PP., 1997. [8] GAMMA, E., R. HELM, H. JOHNSON und J. VLISSIDES: Entwurfsmuster: Elemente wiederverwendbarer objektorientierter Software. Addison-Wesley, 1996. [9] JOHNOSON, R.: An Introduction to Patterns, Reports on Object Analysis and Design, Bd.1, Nr.1. SIGS Publications, 1994, Mai-Juni. [10] PRECHELT, L., B. UNGER, M. PHILIPPSEN und W.F. TICHY: Two Controlled Experiments Assessing the Usefulness of Design Pattern Information During Program Maintenance, Program Maintenance, Empirical Software Engineering. 1997. Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 11 LITERATURVERZEICHNIS 38 11 Literaturverzeichnis 11.1 Literaturliste Christopher Alexander, u.a.: A Pattern Language´ Oxford University Press, New York, 1977 Erich Gamma, Richard Helm, Ralph Johnson, John Vlissides - called: GoF (Gang of Four): Design Patterns: Elements of Object-Oriented Software, Addison-Wesley Professional, 1994 C. Martin, Dirk Riehle, Frank Buschmann: Pattern Languages of Program Design 3 Pearson Education, 1st edition, October 7, 1997 Alan Shalloway, James R. Trott: Design Patterns Explained: A New Perspective on Object-Oriented Design Addison-Wesley Professio- nal, August 2001 11.2 Online Literaturliste ET++: http://www.ubilab.com/ Last visit on 29.11.2004 - 8:23PM Oopsla: http://www.oopsla.org Last visit on 29.11.2004 - 8:24PM University of Illinois at Springfield: http://www.uiuc.edu Last visit on 29.11.2004 - 8:25PM Patterns of interaction in eXtreme Programming: http://polo.lancs.ac.uk Last visit on 29.11.2004 - 8:26PM Christopher Alexander: An Introduction for Object-Oriented Designers: http://www.patternlanguage.com Last visit on 29.11.2004 - 8:27PM RedAmbivalentPatterns Inc.: http://www.RDP.com Last visit personal on 29.11.2004 - 3:40AM Refactoring: http://www.refactoring.com Last visit on 29.11.2004 - 8:28PM Cunningham and Cunningham, Inc.: http://www.c2.com Last visit on 29.11.2004 - 8:29PM Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 39 12 VERWENDETE NOTATIONEN 12 Verwendete Notationen Eine Notation im Kontext der Dokumentation und Klassifikation ist ein Ausdruck zur verkürzten Darstel- lung einer Klasse und/oder von Relationen zwischen Klassen in Klassifikationssystemen. Sie wird nach den Regeln eines spezifischen Notationssystems gebildet, dessen Zeichenvorrat aus Zahlen, Sonderzei- chen und Buchstaben bestehen kann. Ein prominentes Beispiel sind die Notationen der Universellen Dezimalklassifikation (UDK), in der die einzelnen Klassen durch Ziffernfolgen repräsentiert werden. Mit Hilfe eines genormten Systems von An- hängezahlen und Symbolen können komplexere Notationen gebildet werden (Beispiele siehe im Artikel über die UDK). Die Notation bildet oft einen Bestandteil der Signatur, die als Standortbezeichnung einzelner Exemplare eines Buches oder anderer Publikationen in einer Bibliothek dient. Es werden drei unterschiedliche diagrammatische Notationen verwendet: 1. Ein Klassendiagramm zeigt Klassen, ihre Struktur, und die statischen Beziehungen zwischen ihnen. 2. Ein Objektdiagramm zeigt eine bestimmte Objektstruktur zur Laufzeit. 3. Ein Interaktionsdiagramm zeigt den Fluss von Anfragen zwischen Objekten. Ein Entwurfsmuster umfasst immer mindestens ein Klassendiagramm. Alle anderen Notationen werden je nach Anwendungsfall angewendet. Diese Notationen unterstützen die Diskussion im Bedarfsfall. • Klassen- und Objektdiagramme basieren auf OMT (Objekt Modeling Technique) • Interaktionsdiagramme basieren auf Objectory und der Booch-Methode Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 12 VERWENDETE NOTATIONEN 40 12.1 Klassendiagramme OMT-Notation für abstrakte und konkrete Klassen: Klassendiagramme beschreiben Objekt-Klassen durch Angaben der • Operationen (Methoden / Funktionen) • Zustände (Attribute) • Beziehungen (Assoziationen / Relationen) Abbildung 13: Beispiel: Klassendiagramm Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 41 12.2 Objektdiagramme 12.2 Objektdiagramme Objektdiagramme zeigen ausschließlich Objekte. Die Objekte in einem Entwurfsmuster heißen wie die Klassen des Objekts. Das Objektdiagramm gehört zu den statischen Diagrammen der UML. Es zeigt Ausprägungen der im Klassendiagramm modellierten Typen zu einem bestimmten Zeitpunkt. Folgende Notationselemente werden im Objektdiagramm eingesetzt: • Objekt (Ausprägung einer Klasse), • Link (Ausprägung einer Assoziation) • Wert (z. B. eines Attributs) Bei der Modellierung kann das Objektdiagramm eingesetzt werden, um in einer konkreten „ Moment- aufnahme“ komplexere Strukturen zu betrachten. Abbildung 14: Beispiel: Objektdiagramm Seminararbeit: Carsten Thelen und Jan Philipp Seng
  • 12 VERWENDETE NOTATIONEN 42 12.3 Interaktionsdiagramme Interaktionsdiagramme stellen die Reihenfolge dar, in welcher die Anfragen zwischen den Objekten ausgeführt werden. Ein Ablaufdiagramm, auch Organigramm, ist eine Veranschaulichung von Programmabläufen. Beispiele sind das Nassi-Shneiderman-Diagramm oder das Flussdiagramm. Ablaufdiagramme werden von Pro- grammierern verwendet, um die Funktionsweise eines Computerprogramms oder eines Algorithmus zu veranschaulichen. Sie können auch zur Darstellung von beliebigen Prozessen und Tätigkeiten verwendet werden, beispielsweise zur Entscheidungsfindung in Reparaturanleitungen, Darstellung von Geschäfts- modellen, medizinischen Diagnostik usw. Abbildung 15: Beispiel Interaktionsdiagramm Seminararbeit: Jan Philipp Seng und Carsten Thelen
  • 43 13 IMPRESSUM 13 Impressum Carsten Thelen T-SYSTEMS GEI GmbH Pascalstrasse 14 52076 Aachen Jan Philipp Seng FH Aachen, FB 8 Goethestrasse 1 52064 Aachen Seminararbeit: Carsten Thelen und Jan Philipp Seng