Hallo Hagen, hallo scouty,
Zitat:
@choose: die .CommonMethod() in meinem Beispiel zeigt wie es
OOP konform zu lösen ist.
Hier wird aber leider kein unterschiedliches Verhalten in Abhängigkeit der konkreten Klasse erreicht (wie zB bei der Polymorphie).
@scouty: Es ist ein typisches Verhalten von "Neuligen" der
OOP, jede Problemstellung über Vererbung lösen zu wollen. Zwar ist diese Technik ein herausragendes Kriterium der
OOP, trotzdem ist sie statisch und in hohem Maße unflexibel.
Für Deine konkrete Anforderung, sollte sie, sofern wirklich nur das das Schließen gemeint ist, jedoch mithilfe des
template method pattern vollkommen ausreichen:
Zitat von
GoF:
[..]Use a skeleton of the algorithm in the operation. Subclasses can redefine the certain steps in the algorithm without changing the algorithm's structure.
Zunächst einmal ändere ich Deine Hierarchie
Code:
TBscFrm
\- TDBEdtFrm
\- TDBEdtFrmChild
nach
Code:
TBscFrm
\- TCustomDBEdtFrm (abstract)
\- TDBEdtFrm
\- TDBEdtFrmChild
so dass in
TCustomDBEdtFrm das von dir beschriebene in
TDBEdtFrm und
TDBEdtFrmChild verwendete
DB-Verhalten implementier wird.
Anschließend verwende ich in
FormClose, dem Eventhandlet von
OnClose das oben erwähnte Template Method-Pattern wie folgt
Delphi-Quellcode:
type
TCustomDBEdtFrm = //..
procedure FormClose(Sender: TObject);
protected
procedure DoCustomBeforeClose; virtual;
procedure DoCustomAfterClose; virtual;
//..
end;
procedure TCustomDBEdtFrm.DoCustomBeforeClose;
begin
//do nothing (template method pattern)
end;
procedure TCustomDBEdtFrm.DoCustomAfterClose;
begine
//do nothing (template method pattern)
end;
procedure TCustomDBEdtFrm.FormClose(Sender: TObject);
begin
// call redefined code (template method pattern)
DoCustomBeforeClose;
// do some generic close behavior
//..
// call redefined code (template method pattern)
DoCustomAfterClose;
end;
so dass ein spezifischer Teil in einem der konkreten Erben angepasst werden kann
Delphi-Quellcode:
type
TDBEdtFrm = class(TCustomDBEdtFrm)
protected
procedure DoCustomAfterClose; override;
end;
procedure TDBEdtFrm.DoCustomAfterClose;
begin
// free allocated ressources
end;
Die entsprechenden Teile der Logik werden somit an die Unterklasse delegiert...
Es fällt auf, dass sich diese Lösung nur eignet, um triviale Probleme zu lösen: Müssen
DoCustomAfterClose und
DoCustomBeforeClose unterschiedlich implementiert werden, obgleich die übrige Logik der Klasse unverändert bleibt, könnte es mit diesem Muster zu einer "Explosion" von Unterklassen kommen.
Eine gängige Lösung bietet hier das
strategy pattern, das in Delphi auch über
Events gelöst werden kann. Stelle Dir diesen Ansatz vereinfacht so vor, als wenn Du ein nur für die Klasse und alle Erben sichtbares Eregnis (ähnlich wie
OnClick) mit einer optionalen Ereignisbehandlungsroutine (vergleichbar mit
Button1Click) verknüpfst. Statt also in der oben skizzierten Version von
FormClose direkt
DoCustoAfterClose aufzurufen, sähe dieser Ansatz eine weitere Delegation vor...