MVC-Uhr Siehe auch K. Merkert HSG-Kaiserslautern Speyer, 13.09.05 Helmut Paulus MPG Trier
Modellierung der Klassen Klassendiagramm Modell Datenklasse Fachkonzeptklasse (Unit: mTUhr.pas) GUI-Klasse Ansicht, Steuerung (Unit: uUhrform.pas)
Formularklasse: TUhrForm type TFUhr = class(TForm) Ed_H: TEdit; Ed_Min: TEdit; Btn_setzen: TButton; Btn_abfragen: TButton; Label1: TLabel; L_Anzeige: TLabel; procedure Btn_abfragenClick(Sender: TObject); procedure Btn_setzenClick(Sender: TObject); procedure FormCreate(Sender: TObject); procedure FormDestroy(Sender: TObject); private { Private-Deklarationen} public { Public-Deklarationen} Uhr : TUhr; end; var UhrForm: TUhrForm; TFUhr wird von TForm abgeleitet Referenzvariable für das Uhrenobjekt Uhr <- nil Referenzvariable für das Formularobjekt
Implementierung Fensterereignisse procedure TUhrForm.FormCreate(Sender: TObject); begin Uhr := TUhr.create; end; procedure TUhrForm.FormDestroy(Sender: TObject); Uhr.Free Erzeugung des Uhrenobjekts Variable Uhr erhält einen Zeiger auf das Objekt Zerstörung des Objekts (Speicherfreigabe)
Implementierung Uhr anzeigen Uhr setzen Controller-Ereignisse procedure TUhrForm.Btn_abfragenClick(Sender: TObject); var h,min : integer; sh,smin : string; begin h := Uhr.GetH; min := Uhr.GetMin; sec := Uhr.getSec; if length(sh) = 1 then sh := '0'+sh; if length(smin) = 1 then smin := '0'+smin; if length(ssec) = 1 then ssec := '0'+ssec; L_Anzeige.caption := sh+':'+smin; end; procedure TUhrForm.Btn_setzenClick(Sender: TObject); var h,min : integer; h := StrToInt(Ed_H.text); min := StrToInt(Ed_Min.text); Uhr.SetH(h); Uhr.SetMin(min); Uhr anzeigen Abfragen der Uhrendaten Ansicht aktualisieren Uhr setzen Speichern der Uhrendaten
Uhr mit Ereignis
Ein Ereignis für das Uhrobjekt Das Uhrobjekt soll die Ansicht über Datenänderungen informieren. Dazu wird ein Ereignis implementiert, das bei Datenänderung ausgelöst wird, also in den set-Methoden. Das Modell erhält einen Methodenzeiger, der mit einer Methode des Formulars verknüpft werden kann. Die Implementation erfordert in vier Schritte: Vereinbarung eines Methodenzeiger-Typs Vereinbarung eines Methodenzeigers Aufruf der Ereignisprozedur über den Methodenzeiger Zuweisung einer Ereignisprozedur Die Schritte (1) – (3) erfolgen im Modellobjekt, Schritt (4) im Formular.
Implementation des Ereignisses Ereignis: OnChanged vom Typ TChangeEvent type TOnChanged = procedure of object; (1.) TUhr = Class .... public ... OnChanged : TOnChanged; (2.) end; Methode ohne Parameterliste Deklaration eines Methodenzeigertyps (hier: für eine Prozedur ohne Parameter) Deklaration einer Referenzvariablen vom Typ des Methodenzeigers
Auslösen des Ereignisses Modell: procedure TUhr.setH(wert : integer); begin FH := wert; //GUI informieren if assigned(OnChanged) then OnChanged; (3) end; 3. Ereignis auslösen Wirkung: Das Modellobjekt ruft eine Methode des GUI-Objekts auf, wenn sich seine Daten ändern.
Ereignisbearbeitungsmethode GUI-Klasse: type TUhrForm = class(TForm) ... private Uhr : TUhr; procedure updateView; public end; Ereignismethode vom Typ des Methodenzeigers Implementierung: procedure TUhrForm.updateView; begin //wird vom Modell aufgerufen ... end;
Setzen des Methodenzeigers GUI-Klasse: 4. Verknüpfen des Methodenzeigers mit OnCreate-Ereignis procedure TUhrForm.FormCreate(Sender: TObject); begin Uhr := TUhr.create; Uhr.OnChanged := updateViews; (4) end;
Uhr mit Timer
Modell-Klasse Das Uhrenobjekt erhält eine private Timerkomponente, die die Zeit im Sekundentakt erhöht. Klassendiagramm Hat - Beziehung OnTimer - Ereignis -Timer : Referenz auf das Timerobjekt -!ticke : Ereignismethode (OnTimer) Das Uhrenobjekt ist für die Erzeugung und Zerstörung des Timerobjekts zuständig.
Implementierung Objektreferenz Ereignismethode des Timers uses extctrls; type TUhr = Class private FH : integer; Fmin : integer; FSec : integer; Timer : TTimer; procedure ticke(Sender:TObject); public constructor create; destructor destroy; override; ... end; wegen TTimer Objektreferenz Ereignismethode des Timers
Implementierung Freigabe des Objekts constructor TUhr.create; begin Timer := TTimer.create(nil); with Timer do interval := 1000; enabled := true; OnTimer := ticke end; destructor TUhr.destroy; Timer.free; inherited destroy; Erwartet wird eine Referenz auf den Besitzer der Komponente: Objekt vom Typ TComponent oder nil. Methodenzeiger mit der Ereignismethode verknüpfen Freigabe des Objekts Aufruf des Destruktors der Basiskalsse TObject TUhr ist unmittelbar von TObject abgeleitet und kann daher nicht Besitzer (owner) einer Komponente sein.