Abschluss zu Entwurfsmustern: Ausflug in weitere Erzeugungsmuster • Mustername: • • • • • variabel gemachter Aspekt Factory Method: Implementierungsvarianten Abstract Factory: Familien von Implementierungsvarianten Builder: Repräsentation komplexer Objekte Prototype: Repräsentation komplexer Objekte Singleton: globaler Konstruktorzugriff mit Sicherstellung, daß genau eine Instanz erzeugt wird Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Beispiel: Repräsentation von Adressen • Information und Repräsentation: – Häufig wird die gleiche Information (z.B. eine Adresse) programmtechnisch verschieden realisiert. » Standards zum Austausch mit anderen Systemen » Interaktion mit Fremdsystemen – Programmstrukturen sollten klar unterscheiden zwischen reiner Informationsverarbeitung (repräsentationsunabhängig) und Bearbeitung einzelner Repräsentationen. • Vereinfachendes Beispiel: – Adressinformationen – Repräsentation 1: Strukturiert » Felder für die Adressbestandteile » Ausgabe als formatierter String – Repräsentation 2: XML-String » XML-Elemente für die Adressbestandteile » Flexibilität bezüglich der Element-Reihenfolge Technische Universität Dresden Prof. Hußmann Seite 1 Softwaretechnologie II Repräsentation 1: Strukturiert class AddressStruct { public public public public public public public public public public String name; String firstName; String company; String orgUnit1; String orgUnit2; String street; int number; String postCode; String city; String country; public AddressStruct(String name, String firstName, String street, int number, String postCode, String city, String country){ ... } public String toString() { return firstName+" "+name+"\n"+ (company!=null ? company+"\n" : "")+ ... } } Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Repräsentation 2: XML class AddressXml { private String xmlString = ""; public void addName(String name) { xmlString += " <name>"+name+"</name>\n"; } public void addFirstName(String firstName) { xmlString += " <firstName>"+firstName+"</firstName>\n"; } ... public String toString() { return "<address>\n"+xmlString+"</address>\n"; } } Grundidee des Beispiels: Es wird in zwei Repräsentationen eine verschiedene "Philosophie" z.B. bezüglich der Erzeugungsreihenfolge und der Granularität der Operationen verwendet. Technische Universität Dresden Prof. Hußmann Seite 2 Softwaretechnologie II Erzeugungsmuster Builder • Problem: Es ist ein komplexes Produkt zu erzeugen, dessen Zerlegung sinnvollerweise in Einzelschritte zerlegt wird. Es existieren verschiedene Repräsentationen des Produkts mit u.U. verschiedenen Erzeugungsschnittstellen. • Lösung: Entkopplung von konkretem, repräsentationsbezogenem ErzeugerObjekt und allgemeiner Erzeugungsschnittstelle. AbstractBuilder Director buildPart1() buildPart2() ... getProduct: ProductIF construct() <<interface> <<use>> ProductIF <<create>> Product Technische Universität Dresden ConcreteBuilder buildPart1() buildPart2() ... getProduct: ProductIF Prof. Hußmann Softwaretechnologie II Strukturmuster Marker Interface • Problem: Semantische Gemeinsamkeiten von Klassen beschreiben • Lösung: "Leere" Schnittstelle verwenden • Vorteil: Viele Muster, die abstrakte Schnittstelle voraussetzen, werden anwendbar. • Hinweis: Kein "Gang of Four"-Muster, Quelle: M. Grand (Vol. 1) • Beispiel: interface AddressIF { } class AddressStruct implements AddressIF { ... } class AddressXml implements AddressIF { ... } Technische Universität Dresden Prof. Hußmann Seite 3 Softwaretechnologie II Beispiel-Code zu Builder (1) abstract class AddressBuilder { protected AddressBuilder() {}; public static AddressBuilder getInstance(String reprType) { if (reprType.equals("Struct")) return new StructBuilder(); if (reprType.equals("XML")) return new XmlBuilder(); return null; } public public public public public public public public public public abstract void setName(String n); abstract void setFirstName(String fn); void setCompany(String c) {}; void setOrgUnit1(String ou1) {}; void setOrgUnit2(String ou2) {}; abstract void setStreet(String s); abstract void setNumber(int n); abstract void setPostCode(String pc); abstract void setCity(String c); abstract void setCountry(String c); public abstract AddressIF getAddress(); } Technische Universität Dresden Prof. Hußmann Datei: Address.java Softwaretechnologie II Beispiel-Code zu Builder (2) class StructBuilder extends AddressBuilder { private String name; private String firstName; private String company; ... public void setName(String n) { name = n; } public void setFirstName(String fn) { firstName = fn; } ... public AddressIF getAddress() { AddressStruct as = new AddressStruct(name, firstName, street, number, postCode, city, country); as.company = company; as.orgUnit1 = orgUnit1; as.orgUnit2 = orgUnit2; return as; } } Technische Universität Dresden Prof. Hußmann Seite 4 Softwaretechnologie II Beispiel-Code zu Builder (3) class XmlBuilder extends AddressBuilder { private AddressXml ax = new AddressXml(); public void setName(String n) { ax.addName(n); } public void setFirstName(String fn) { ax.addFirstName(fn); } public void setCompany(String c) { ax.addCompany(c); } ... public AddressIF getAddress() { return ax; } } Technische Universität Dresden Prof. Hußmann Softwaretechnologie II 5. Wiederverwendung im Softwareentwurf 5.2 Frameworks Literatur: T. Lewis et al.: Object-oriented application frameworks, Manning 1995 http://www.ibm.com/software/developer/library/oobuilding (früher: taligent.com) Building Object-oriented Frameworks: W. Pree: Komponentenbasierte Softwareentwicklung mit Frameworks, dpunkt 1997 Technische Universität Dresden Prof. Hußmann Seite 5 Softwaretechnologie II Wiederverwendung vs. Neuentwicklung • Typische Programmiereransicht: "Wiederverwendung kostet genauso viel Aufwand wie neu schreiben." • Diese Ansicht ist teilweise richtig ! Aufwand für Wiederverwendung (als Anteil des NeuentwicklungsAufwands) 100% 55% Umfang der Anpassungen 12% 100% Quelle: NASA-Studie 1994 Technische Universität Dresden (an wiederverwendeter Komponente) Prof. Hußmann Softwaretechnologie II Technologien für Wiederverwendung • • • • • Bausteinsysteme (componentware) Frameworks Architekturmuster und Referenzarchitekturen Entwurfsmuster Klassenbibliotheken Abnehmende Festlegung der Architektur • Grundidee: Softwareentwurf für Wiederverwendung • Vielfältiger Einsatz von Mustern: MusterAnwendungsprogramm verwendung Technische Universität Dresden MusterApplication Framework verwendung Prof. Hußmann Seite 6 Bausteinsystem Softwaretechnologie II Frameworks • Definition (Taligent): „A framework is a set of prefabricated software building blocks that programmers can use, extend, or customize for specific computing solutions.“ • Definition (nach Pomberger/Blaschek): Ein "framework" (Rahmenwerk, Anwendungsgerüst) ist eine Menge von zusammengehörigen Klassen, die einen abstrakten Entwurf für eine Problemfamilie darstellen. • Ziele: – Wiederverwendung von Code, Architektur und Entwurfsprinzipien – Wiederverwendung von Verhaltensschemata einer Gruppe von Klassen – Homogenität unter verschiedenen speziellen Anwendungssystemen für eine Problemfamilie (z.B. ähnliche, ergonomische Bedienung) Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Klassifikation nach Einsatzart • Anwendungs-Framework (Application Framework): – Rahmen für eine ganze Anwendung – Beinhalten Expertenwissen zur Systemarchitektur, das auf ähnlich geartete Programme anwendbar ist » z.B. GUI-Frameworks » "micro-framework" = Rahmenlösung für Teilsystem (z.B. Datenbankanbindung) • Bereichsspezifisches Framework (Domain Framework): – Beinhalten Expertenwissen zu speziellem Anwendungsbereich » z.B. Framework für Anlagensteuerungen » z.B. Framework für betriebswirtschaftliche Anwendungen » z.B. Multimedia-Framework • Infrastruktur-Framework (Support Framework): – Bereitstellung von Systemdiensten » z.B. Framework zur Anpassung von Gerätetreibern Technische Universität Dresden Prof. Hußmann Seite 7 Softwaretechnologie II Klassifikation nach Architektur • Architektur-getriebenes Framework (architecture-driven): – – – – Anpassung durch Vererbung und Überdefinieren Komplexe Klassenhierarchien und Muster Relativ viel neuer Code zu schreiben Anpassung erfordert sehr hohen Einarbeitungsaufwand • Daten-getriebenes Framework (data-driven): – – – – Anpassung durch Objektkonfiguration und Parametereinstellung Weitergeleitete Objekte bestimmen Verhalten (z.B. Ereignis-Objekte) Relativ einfach anzupassen Eingeschränkte Flexibilität sh. Komponentensysteme (5.3)! • Möglicher und sinnvoller Kompromiß: – Zwei-Schichten-Architektur: daten-getrieben architektur-getrieben Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Vergleich Klassenbibliothek-Framework Klassenbibliothek Framework Anwendungsspezifische Teile Vorgefertigte Teile "Don't call us, we call you" („Hollywood-Prinzip“) Anpassung nur durch Instanziierung Anpassung auch durch Spezialisierung Ablaufsteuerung nicht vordefiniert Ablaufsteuerung im wesentlichen vordefiniert Die Grenze ist fließend, siehe z.B. Java AWT ! Technische Universität Dresden Prof. Hußmann Seite 8 Softwaretechnologie II Beispiel: Schließbares Fenster in Java AWT import java.awt.*; import java.awt.event.*; class WindowCloser extends WindowAdapter { public void windowClosing(WindowEvent event) { System.exit(0); } } class ExampleFrame extends Frame { public ExampleFrame () { setTitle("untitled"); setSize(150, 50); addWindowListener(new WindowCloser()); setVisible(true); } } class GUI1 { public static void main (String[] argv) { ExampleFrame f = new ExampleFrame();}} Technische Universität Dresden Prof. Hußmann Softwaretechnologie II java.awt.event.WindowListener public interface WindowListener extends EventListener { public void windowClosed (WindowEvent ev); public void windowOpened (WindowEvent ev); public void windowIconified (WindowEvent ev); public void windowDeiconified (WindowEvent ev); public void windowActivated (WindowEvent ev); public void windowDeactivated (WindowEvent ev); public void windowClosing (WindowEvent ev); } java.util.EventListener: Basis für alle "Listener" Keine Operationen Technische Universität Dresden Prof. Hußmann Seite 9 Softwaretechnologie II java.awt.event.WindowAdapter public abstract class WindowAdapter implements WindowListener { public public public public public public public void void void void void void void windowClosed (WindowEvent ev) {} windowOpened (WindowEvent ev) {} windowIconified (WindowEvent ev) {} windowDeiconified (WindowEvent ev) {} windowActivated (WindowEvent ev) {} windowDeactivated (WindowEvent ev) {} windowClosing (WindowEvent ev) {} } Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Schließbares Fenster: Klassenstruktur <<interface>> WindowListener Window windowClosing (e: WindowEvent) addWindowListener (l: WindowListener) <<use>> WindowEvent setSize setTitle setVisible WindowAdapter WindowCloser Technische Universität Dresden Frame registriert bei Prof. Hußmann Seite 10 ExampleFrame Softwaretechnologie II Entwurfsmuster Template Method • Verhaltensmuster • Problem: Schematisches Verhalten einer Operation soll an bestimmten Stellen veränderbar gemacht werden. • Lösung: Schablonenmethode (template method) und Einschubmethoden (hook methods) AbstractClass {abstract} method1 {abstract} method2 {abstract} method3 method3 () { ...; ...; method1(); ...; ...; method2(); } ConcreteClass method1 method2 Technische Universität Dresden Prof. Hußmann Softwaretechnologie II Entwurfsmuster Strategy • Verhaltensmuster • Problem: Ein Algorithmus aus einer Familie verwandter Algorithmen soll austauschbar gemacht werden. • Lösung: Verkapseln des Algorithmus in einem austauschbaren Strategie-Objekt Context Strategy {abstract} strategy algorithm() {abstract} strategy.algorithm() Technische Universität Dresden ConcreteStrategyA ConcreteStrategyA algorithm() algorithm() Prof. Hußmann Seite 11 Softwaretechnologie II Vor- und Nachteile von Frameworks • Vorteile: – – – – – – Weitergabe von Expertenwissen Durchdachtes Design führt zu langfristiger Aufwandsersparnis Wartungsaufwand wird reduziert Gute Möglichkeiten für systematische Tests Prinzipiell sehr hohe Produktivität möglich Erleichtert Integration und Konsistenz verwandter Anforderungen • Nachteile: – – – – – Erstellung von Frameworks aufwendig Einarbeitung in Frameworks aufwendig Zusätzlicher Dokumentations- und Wartungsaufwand Fehlersuche erschwert durch Overhead des Frameworks Kombination von verschiedenartigen Frameworks sehr schwierig The most profoundly elegant framework will never be reused unless the cost of understanding it and then using its abstractions is lower than the programmer's perceived cost of writing them from scratch. G. Booch 1994 Technische Universität Dresden Prof. Hußmann Seite 12 Softwaretechnologie II