Vorbereitung zu Praktikum 3

Slides:



Advertisements
Ähnliche Präsentationen
der Universität Oldenburg
Advertisements

der Universität Oldenburg
der Universität Oldenburg
Strategie (Strategy / Policy) Ein objektbasiertes Verhaltensmuster Stephan Munkelt, Stefan Salzmann - 03IN.
Progwerkstatt JAVA Klasse, Objekte, Konstruktoren, Methoden
Kapitel 4 Datenstrukturen
Seminar: "Einführung in C/C++" Einführung in die Programmiersprache C/C++ Donnerstag Andreas Döring SS 2004.
Christos, Kornelia, Jan Christos, Kornelia, Jan Entwicklungsumgebung Versteht unseren Java Programm Code Versteht unseren Java Programm.
Java: Objektorientierte Programmierung
Java: Dynamische Datentypen
Indirekte Adressierung
Java: Grundlagen der Objektorientierung
Wie überwacht man Objekte im "Alltag" ?. Indem man "Wanzen" an diese anbringt.
Ein Beispiel in Java.
Konstruktoren.
Polymorphie (Vielgestaltigkeit)
Polymorphie (Vielgestaltigkeit)
Dynamischer Speicher. In einer Funktion wird z.B. mit der Deklaration int i; Speicher auf dem sogenannten Stack reserviert. Wenn die Funktion verlassen.
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
Universität Dortmund, Lehrstuhl Informatik 1 EINI II Einführung in die Informatik für Naturwissenschaftler und Ingenieure.
Sebastian Grahn Sebastian Kühn
Abstrakter Datentyp in C++ I - Klasse -
Programmierpraktikum eXtreme Programming 2005
Objektorientierte Programmierung
Command Pattern Karola Schäuble,
UNDO & SELECT Vortrag : Martin Hiersche
C++ Vererbung und Polymorphie
DVG Einführung in Java1 Einführung in JAVA.
DVG Klassen und Objekte
Einführung in die Programmierung Datensammlung
Tipps und Tricks für Word 2000 Aytac, Felix, Steffen 04/05.
Prof. Dr. Gerhard Schmidt pres. by H.-J. Steffens Software Engineering SS 2009Folie 1 Objektmodellierung Objekte und Klassen Ein Objekt ist ein Exemplar.
Einführung in die Programmierung Wintersemester 2013/14 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Informatik 1 Übung 8. NACHBESPRECHUNG Übung 8 Rekursion Existiert Weg von A nach B?
Objektorientierte Programmierung
Einführung in die Programmierung
Von der Planung bis zum Hauptmenü Seminar: Softwaretechnologie II Dozent: Prof. Manfred Thaller Referent: Jan Bigalke.
Einführung in die Programmierung Wintersemester 2009/10 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure
Einführung in die Programmierung Wintersemester 2008/09 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Einführung in die Informatik für Naturwissenschaftler und Ingenieure (alias Einführung in die Programmierung) (Vorlesung) Prof. Dr. Günter Rudolph Fachbereich.
Einführung in die Programmierung Wintersemester 2010/11 Prof. Dr. Günter Rudolph Lehrstuhl für Algorithm Engineering Fakultät für Informatik TU Dortmund.
Windows Presentation Foundation, Vorlesung Wintersemester 2013/14 Prof. Dr. Herrad Schmidt WS 13/14 Kapitel 8 Folie 2 Commands (1) s.a.
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
Dynamische Datentypen
Aufgaben Version 1: Es soll eine Wetterstation mit folgenden zwei Anzeigen implementiert werden: Aktuelle Wetterbedingungen mit Temperatur und.
Java Programmierung.
Objectives Verstehen was unterDelegate verstanden wird
EPROG Tutorium #4 Philipp Effenberger
Das Command Muster Deimbacher, Gölles.
Polymorphie (Vielgestaltigkeit). Wenn eine Methode, wie z.B. print für verschiedene Programmteile steht (und z.B. einmal Objekte verschiedener Klassen.
Informatik I : Software höhere Programmiersprachen Java Klassen: hat Methoden (Funktionen) und Daten (Variablen) es kann mehrere Klassen geben nur eine.
OOP-Begriffe Abstraktion Modellieren Klasse Objekt Attribute Methoden
2 Datenabstraktion Geheimnisprinzip:
Java-Kurs Übung Besprechung der Hausaufgabe
Einführung in die Programmierung mit Java
Institut für Kartographie und Geoinformation Prof. Dr. L. Plümer, Dipl.-Ing. D. Dörschlag, Dr. G. Gröger Einführung in die Programmierung mit Java 13.
IT2 – WS 2005/20061Nov 14, 2005 Visibility  public: Sichtbar in allen Paketen  protected: Sichtbar innerhalb des Pakets und in den Unterklassen  (default,
Erweiterte Zuweisungskompatibilität. Wie kann man Objekte verschiedener Klassen einer Klassenhierarchie einander zuweisen ?
Vererbung. Klassen - Vererbung  Eine Klasse kann von einer Basisklasse abgeleitet werden  Die abgeleitete Klasse erbt die Eigenschaften und Methoden.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
Tutorium Software-Engineering SS14 Florian Manghofer.
C++ FÜR cOMPUTERSPIELENTWICKLER
Tutorium Software-Engineering SS14 Florian Manghofer.
Von Cem, Maurice und lars
Implementieren von Klassen
Informatik Softwareentwicklung – 4.3 Entwurfsmuster
 Präsentation transkript:

Vorbereitung zu Praktikum 3 Menü-Toolkit und Command Pattern

Fallstudie zu Vererbung und Polymorphie: "Menü-Toolkit" Anwenderfreundliche Programme werden mit Menüs gesteuert In OO-Anwendungen werden Menüs und Menüeinträge durch Objekte repräsentiert. Ein rudimentäres Menü (Objekt vom Typ Menu) besteht mindestens aus einem Titel (z.B. Member titel vom Typ string) mindestens einem Menüeintrag (jeder solche Eintrag ist selbst ein Objekt), einer zugeordneten Aktion ( action() ), die alle Menüeinträge anzeigt, den Nutzer zur Auswahl auffordert (prompt) die Nutzerauswahl entgegen nimmt (Maus-Click, Short-Cut), und die den vom gewählten Eintrag angebotenen Service zur Ausführung bringt. * HAUPTMENÜ * c....Copy p....Paste u....Undo r....Redo Ihre Wahl? a

Ein (schlechtes) Klassen Design Menü und Menüeinträge stehen in einer "part-of"-Beziehung (Aggregation). Application Menu Item_Taskx item add(Document) add(MenuItem) remove(MenuItem) action() action() vector<Device> titel prompt shortCut Document vector<MenuItem> titel prompt shortCut open() close() copy() paste() item->action() Client Menu_Base Durch Generalisierung der Klassen Menu und Item_Taskx erhält man diese Vererbungsstruktur. offer() zeigt den Short-Cut und den Titel auf dem Display action()=0 offer() titel, prompt, shortCut ItemOpenDoc Menu action() action() add (Menu_Base*) remove(Menu_Base *) ItemCloseDoc action() vector< Menu_Base *>

Implementierungsansätze class Menu_Base { protected: string _shortCut; string _titel; public: Menu_Base(const string& shortCut, const string& titel) : _shortCut(shortCut), _ titel(titel) { } virtual void action()=0; virtual void offer(); string getShortCut() const; // Accessor string getTitel() const; // Accessor }; Client Menu_Base action()=0 offer() ItemTaskx Menu action() action() add (MenuItem*) remove(MenuItem*) class Menu : public Menu_Base { vector<Menu_Base*> _menuComponents; char _itemSelector; string _prompt; public: Menu( const string& shortCut , const string& titel, const string& prompt ); virtual ~Menu(void); virtual void action(); virtual void add( Menu_Base* mb ); virtual void remove( Menu_Base* mb ); int size() const; int find( const string& shortCut ); }; void Menu::action() { // Alle Menüeinträge auf dem Display anbieten // Dem User die Möglichkeit zur Auswahl bieten // Die Auswahl entgegen nehmen // Den ausgewählten Menüpunkt identifizieren // Für diesen Eintrag action() aufrufen // Fehlerbehandlung bei ungültiger Auswahl. }

Demo class ItemAddDevice : public Menu_Base { Receiver* _prcv; // -> receiver public: ItemAddDevice( const string& shortCut, const string& titel, Receiver *prcv ) : Menu_Base( shortCut, titel ), _prcv(prcv) {} virtual ~ItemAddDevice() {} virtual void action(); }; void ItemAddDevice::action() { // Hierher soll der gesamte Dialog mit dem Nutzer _psh->addDevice(); // Ab hier keine Eignung zum Toolkit }

Demo void Menu::action() { // Menütitel ausgeben cout << _titel << endl; // Alle Menüeinträge auf dem Display anbieten _menuComponents[0]->offer(); // Dem User die Möglichkeit zur Auswahl bieten cout << _prompt; // Die Auswahl entgegen nehmen string selection; cin.clear(); cin.sync(); cin >> selection; // Den ausgewählten Menüpunkt identifizieren int index = find( selection ); // Für diesen Eintrag action() aufrufen this->_menuComponents[index]->action(); // Fehlerbehandlung bei ungültiger Auswahl. }

Warum ist das ein schlechtes Klassendesign? Ein Menü-Objekt verwaltet (Anmeldung, Abmeldung) seine Menü-Einträge in einem Feld. Wird das Menü ausgewählt, so bietet seine Methode action() die Menüeinträge zur Auswahl an. Jedem Menüeintrag ist eine eigene Klasse gewidmet (z.B. ItemOpenDoc oder ItemCloseDoc) die action() im Sinne ihrer Aufgabe redefiniert. Problem: Klassenstruktur des Menü-Toolbox ist dann weitgehend von der speziellen Anwendung bestimmt, in der es eingesetzt wird, und müsste zudem bei jeder neuen Anforderung seitens der Anwendung geändert werden. Als Toolkit bezeichnet man allge-mein eine Sammlung von Bibliotheken, Klassen und Schnittstellen, die das Erstellen von Computerprogrammen vereinfachen sollen. Toolkits müssen nichts von den Anwendungen wissen, die sie benutzen, d.h. es bestehen keine Abhängigkeiten zwischen ihnen. Anwendungen müssen dann nur die Schnittstelle des Toolkits (hier: Schnittstelle der Basisklasse Menu_Base) kennen, um sie benutzen zu können. Kernfrage: Wie soll ein Menüeintragsobjekt einen Service-Auftrag ausführen, ohne etwas über den Serviceerbringer oder die Service-Ausführung zu wissen?

Das Command Pattern Aufgaben Service-Anforderungen an Objekte richten, ohne die Servicedetails und/oder den Empfänger der Anforderung zu kennen Viele Funktionen können von unterschiedlichen Stellen aus aufgerufen werden, z.B. Menüeintrag, Button, Popup-Menü bei Rechtsklick, Tastaturkürzel Soll jedesmal die Funktion dahinter implementiert werden? Befehle sollen rückgängig gemacht werden können (Undo) oder sie sollen erneut ausgeführt werden können (Redo). Wie kann man das speichern, wenn die Operationen eng mit den Objekten, die sie aufrufen, verbunden sind?

Lösungskonzept Den Befehl in einem Objekt kapseln! Das Befehlsobjekt kennt den Befehlsempfänger (Receiver) kennt den von diesem auszuführenden Service (Aktion) weiss auch wie die Aktion rückgängig zu machen ist (merkt sich z.B. den alten Zustand) Vorteile Ein und derselbe Befehl kann von mehreren Objekten aus aufgerufen werden. Die Befehlsobjekte können in einer Befehlshistorie gespeichert werden. als Parameter wie andere Objekte herumgreicht werden, nachdem Sie erzeugt wurden. Entkopplung von Aufrufer und Empfänger eines Befehls: Der Aufrufer braucht den Befehlsempfänger nicht zu kennen, sondern nur die Befehlsschnittstelle.

Entwurfsmuster Command (Command Pattern) Die abstrakte Klasse Command definiert das Interface zur Ausführung eines Befehls ConcreteCommand (z.B. OpenCommand, CopyCommand) implementiert die execute()-Methode der Klasse Command so, dass der Receiver die gewünschte Aktion ausführt. Der Client (meist eine Managerklasse) erzeugt ein ConcreteCommand-Objekt und weist ihm den Receiver zu. Der Invoker (z.B. ein Menüobjekt) fordert sein Befehlsobjekt auf, den Receiver die bekannte Action ausführen zu lassen ( command[i].execute() ) Der Receiver (Textdokument, Anwendung) weiß, wie die entsprechenden Operationen auszuführen sind. http://www.cs.clemson.edu/~malloy/courses/patterns/command.html

Teamwork Sequenzdiagramm der Objekte beim Command Pattern Client (z.B. Managerklasse) erzeugt Command-Objekte und setzt den Receiver. Client übergibt das Command-Objekt an den Aufrufer Aufrufer fordert das Command-Objekt zur Ausführung des Befehls auf. Das Command-Objekt befiehlt dem Receiver die in execute() codierte Aktion. 1. 2. http://www.cs.clemson.edu/~malloy/courses/patterns/command.html 4. 3.

Implementierungsfragen Wie intelligent sollte ein Command sein?  Ein Extrem: Ein Command delegiert die Befehlsausführung sofort an den Receiver. Das andere Extrem: Ein Command (z.B. CopyCommand) implementiert alle anfallenden Aufgaben intern Es liegt im Ermessen des Programmierers, ob er einen der Extremfälle oder irgendwo dazwischen programmiert. Support für Undo und Redo     Dazu muss ConcreteCommand zusätzlichen Speicher reservieren:  für das Receiver-Objekt die der Receivermethode zu übergebenden Parameter für die Orginal-Werte, die bei der Befehlsausführung ggf. geändert werden. Wie vermeidet man Fehlerakkumulation beim Undo-Prozess? indem das command-Objekt ausreichend Daten speichert, um den Orginalzustand wieder herzustellen.  Benutze C++ Templates um nicht für jede Kombination von Receiver und Aktion eine Command-Subklasse deklarieren zu müssen.

Anwendung des Command Patterns beim Menu-Toolkit Application Menu MenuItem Command item cmd add(Document) add(MenuItem) remove(MenuItem) action() action() execute() vector<Document> Command* cmd Document vector<MenuItem> open() close() copy() paste() cmd->execute() Man braucht jetzt nur noch einen Datentyp MenuItem zur Repräsentation der Menüeinträge. Beim Erzeugen eines MenuItem-Objekts durch die Application (=Client) wird ihm der Receiver bekannt gemacht. Nachdem das Menü-Objekt die Benutzerauswahl kennt und das zugehörige MenuItem-Objekt identifiziert hat, fordert es dieses auf, bei seinem Receiver die Serviceaktion abzurufen. Die abstrakte Klasse Command definiert für diesen Zweck eine einheitliche Schnittstelle in Form der Methode execute() Von Command abgeleitete Klassen (z.B. CommandOpen, CommandCopy, ...) redefinieren diese Methode und delegieren dabei ihrerseits die übernommene Aufgabe an den dafür vorgesehenen Receiver.