Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   GUI-Design mit VCL / FireMonkey / Common Controls (https://www.delphipraxis.net/18-gui-design-mit-vcl-firemonkey-common-controls/)
-   -   Delphi Exception in Basis-Klasse abfangen? (https://www.delphipraxis.net/108410-exception-basis-klasse-abfangen.html)

mjenke 13. Feb 2008 05:51


Exception in Basis-Klasse abfangen?
 
Guten Morgen, alle miteinander!

Folgendes Problem stellt sich mir:

Nehmen wir an, ich habe eine Basis-Klasse und n Klassen, die ich von ihr ableite. Gibt es eine Möglichkeit, ein Exception-Handling in der Basis-Klasse zu implementieren, das Exceptions aus den abgeleiteten Klassen abfängt? :gruebel:

Ein Beispiel:

TBase ist meine Basis-Klasse
TSub ist abgeleitet von TBase (TSub = class (TBase)).

Wenn ich nun in einer Methode von TSub in eine Exception gerate, möchte ich dass eine entsprechende Routine in TBase darauf reagiert. Und zwar so, dass ich nicht unbedingt in TSub im Exception-Fall die Methode aus TBase aufrufe. TBase soll sozusagen als Listener selbst darauf achten, dass in den von ihr abgeleiteten Klassen alles mit rechten Dingen zugeht...
:mrgreen:

Hintergrund ist einfach der, dass ich verschiedenste Klassen von meiner Basis ableiten muss (für Datenbankzugriffe unterschiedlichster Art), die aber alle in die gleichen Probleme geraten können. Und ich möchte nicht überall von Hand eingreifen müssen, sondern dieses Problem (wenn möglich) einmal in der Basis lösen.

:-D

jottkaerr 13. Feb 2008 06:09

Re: Exception in Basis-Klasse abfangen?
 
Hallo,

mach das ganze mit dem Template-Muster:

Delphi-Quellcode:
type
  TBase = class(TObject)
  protected
    procedure DoThis; virtual;
    procedure DoThat; virtual;
  public
    procedure Work;
  end;

  TDerived = class(TBase)
  protected
    procedure DoThis; override;
    procedure DoThat; override;
  end;

{ TBase }

procedure TBase.DoThis;
begin
  { ... }
end;

procedure TBase.DoThat;
begin
  { ... }
end;

procedure TBase.Work;
begin
  try
    DoThis;
    DoThat;
  except
    on e: Exception do
      { Exceptions behandeln }
  end;
end;

{ TDerived }

procedure TDerived.DoThis;
begin
  { ... }
  if Error then
    raise Exception.Create('Fehle in TDerivedDoThis!');
  { ... }
end;

procedure TDerived.DoThat;
begin
  { ... }
  if Error then
    raise Exception.Create('Fehle in TDerivedDoThat!');
  { ... }
end;
jkr

mjenke 13. Feb 2008 06:30

Re: Exception in Basis-Klasse abfangen?
 
Hallo, jottkaerr,

vielen Dank für den Tipp, aber der hilft mir leider nicht weiter.

Es gibt nicht eine (oder auch nur eine geringe Anzahl von) Methode(n), die ich in den abgeleiteten Klassen aufrufen muss (in Deinem Beispiel die Methode "Work"). Die Methoden selbst sehen teilweise sehr unterschiedlich aus, haben die unterschiedlichsten Parameter etc.

In dem Fall wäre es tatsächlich einfacher, folgendermaßen vorzugehen:

Delphi-Quellcode:
TBase = class
  protected
    procedure RepairMe;
end;

TDerived = class ( TBase )
  public
    procedure DoSomething;
end;

TDerived2 = class ( TBase )
  public
    procedure DoSomethingCompletelyDifferent;
end;

{...}

{TBase}

procedure TBase.RepairMe;
begin
  {...}
end;

{TDerived}

procedure TDerived.DoSomething;
begin
  try
    ...
  except
    RepairMe;
  end;
end;

{TDerived2}

procedure TDerived2.DoSomethingCompletelyDifferent;
begin
  try
    ...
  except
    RepairMe;
  end;
end;
Aber das ist ja genau der Punkt, den ich gerne vermieden hätte...

sirius 13. Feb 2008 08:14

Re: Exception in Basis-Klasse abfangen?
 
Das geht so einfach nicht.

Man könnte jetzt versuchen zu tricksen. Du könntest im Constrcuter von TBase die virtuelle und/oder die dynamische Methodentabelle umschreiben. Falls das reproduzierbar funktioniert, würden dann eben diese Methoden in allen abgeleiteten Klassen auf eine Methode in TBase umgeleitet werden. (Wenn überhaupt müssten die Methoden dann wahrscheinlich published sein)


Edit: Ordograffie gorrigiert

Edit2: Nach weiterem Nachdenken: geht so nicht

bluesbear 13. Feb 2008 08:52

Re: Exception in Basis-Klasse abfangen?
 
Hallo mjenke,
das ist zwar keine Antwort auf Deine Frage, aber vielleicht hilft es Dir ja weiter:
http://www.madshi.net/madExceptDescription.htm

mjenke 13. Feb 2008 10:18

Re: Exception in Basis-Klasse abfangen?
 
@bluesbear:

Hilft mir wirklich im Moment nicht. Aber trotzdem eine sehr interessante Geschichte. Vielen Dank für den Link!

sirius 13. Feb 2008 12:49

Re: Exception in Basis-Klasse abfangen?
 
Wie unterschiedlich können denn die Deklarationen der Methoden (i.bes. die Anzahl und Art der Parameter) sein?

shmia 13. Feb 2008 13:23

Re: Exception in Basis-Klasse abfangen?
 
Das von jottkaerr beschriebene Template-Muster ist trotzdem die richtige Lösung !!
Für jede Methode gibt es in der Basisklasse einen offiziellen Einstieg und eine virtuelle protected Methode.

Beispiel:

Delphi-Quellcode:
TBase = class(TObject)
  protected
    procedure InternalSaveToFile(const filename:string); virtual; abstract;

  public
    procedure SaveToFile(const filename:string); // die offizielle Methode
end;


procedure TBase.SaveToFile(const filename:string);
begin
  try
    InternalSaveToFile(filename);
  except
    on E:Exception do
    begin
      E.Message:='Fehler beim speichern in Datei <'+filename+'<';
      raise;
    end;
end;
Wenn man sich den Sourcecode von DB.pas und die Basisklasse TDataset anschaut, sieht man, dass Borland
auch das Template-Muster verwendet.
Für jede der wichtigen Methoden Open, close; Edit, Insert, Post,... existiert eine InternalXXXXX Methode.

Apollonius 13. Feb 2008 16:28

Re: Exception in Basis-Klasse abfangen?
 
Andere Möglichkeit: Allen Methoden die Aufrufkonvention Safecall verpassen und in der Basisklasse SafeCallException überschreiben.

sirius 13. Feb 2008 17:32

Re: Exception in Basis-Klasse abfangen?
 
Zitat:

Zitat von Apollonius
Andere Möglichkeit: Allen Methoden die Aufrufkonvention Safecall verpassen und in der Basisklasse SafeCallException überschreiben.

Das funktioniert leider nur bei Delphi-eigenen Exceptions. Aber vielleicht reicht das aus.


Alle Zeitangaben in WEZ +1. Es ist jetzt 07:52 Uhr.

Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz