Re: F: Repeat .... until-Schleifen
- From: Sven Heising <spam@xxxxxxxxxxx>
- Date: Thu, 07 Jul 2005 10:53:01 +0200
Erich Günthner schrieb:
> // Goto
>
>
> Function TFrmMain.CheckSystem : Integer;
> label Label_Fehler;
> begin
> if not CheckHardware(Result) then Goto Label_Fehler;
> if not CheckMultiData(Result) then Goto Label_Fehler;
> if not CheckDevices(Result) then Goto Label_Fehler;
>
> // Tu was anderes
>
> Label_Fehler:
> if Result > 0 then
> ShowMessage('Error: ' + inttostr(Result));
>
> end;
>
> // Exception
>
> Function TFrmMain.CheckSystem : Integer;
> label Label_Fehler;
> begin
> Result := 0;
> Try
> if not CheckHardware(Result) then SysUtils.Abort;
> if not CheckMultiData(Result) then SysUtils.Abort;
> if not CheckDevices(Result) then SysUtils.Abort;
>
> // Tu was anderes
> Except
> ShowMessage('Error: ' + inttostr(Result));
> end;
> end;
>
> Die zwei Code-Stücke machen das gleiche.
> Der eine mit Goto, der andere mit Exception.
> Wo bitte liegt hier der Unterschied? Außer das im ersten Beispiel im
> Label_Fehler nochmal Result abgeprüft wird.
Auch die zweite Lösung mit dem Abort ist nicht das was ich unter OOP
verstehe. So ist da sicher kein Unterschied der nennenswert wäre und man
kann beide als gleichwertig ansehen.
>
> Ich bin auch kein verfechter von Labels.
> Ich wollte hier nur meine Meinung dazu klarlegen, das man Label nicht immer
> gleich verteufeln soll.
> Der eine setzt sie ein, der andere nicht.
Aber keiner der Ahnung hat empfiehlt sie. Es gibt auch Leute die in das
ButtonClick Event grosse Sachen reinprogrammieren. Obwohl es solche
Leute gibt, ist es nciht richtig.
>
> Von der Logk her ist es mir sowieso nicht klar, warum einfache Prüfungen bei
> nicht Erfolg (aber kein Fehler!)
> eine Exception also eine Ausnahme!!!! auslösen sollen.
>
> Oder ist die Püfung: 1 < 2 eine Ausnahme?
>
> Diese Exception werden mittlerweilen eingesetzt, wo immer man Lust hat, oder
> man keine Lust hat anständige Abfragen aufzubauen.
>
> Try
> if 1 < 2 then Sysutils.Abort;
> Result := True;
> Except
> Result := False;
> end;
Das ist sicherlich nochmal ne andere Sache als die geschichte mit den
Labels. Das ist faules Abfragen und ist mit Sicherheit auch nicht i.O.
Ich würde die Fehlerbehandlung für den obigen Code anders machen. Nicht
die CheckMethode sollte den Fehler auslösen sondern die einzelnen
Checkmethoden, die ich als Klassen definieren würde sollten eine
entsprechende Exception (ECheckHardware oder ECheckMultiData ...)
auslösen. Den aufruf würde ich eine gemeinsame Stammklasse lösen, so
kann ich nämlich nie vergessen die Exception zu behandeln, wenn ich
diese Überprüfung nochmal mache. Ich überschreibe also einfach die
abstrakte InternalCheck Methode.
Die Exception übergebe ich dann an einen Exceptionhändler Klasse die
dann entscheiden kann ob und was passieren kann.
Wenn ich jetzt nicht schreibfaul gewesen wäre hätte ich entsprechende
Behandler Klassen von THardwareExeptionHandler abgeleitet und dann statt
der if...then Geschichte für die Behandlung die entsprechende Klasse
erzeugt.
-----------------Anfang Unit Form---------------------------------------
unit test;
interface
uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, StdCtrls;
type
TfrmMain = class(TForm)
Button1: TButton;
procedure Button1Click(Sender: TObject);
private
{ Private declarations }
public
procedure CheckSystem;
{ Public declarations }
end;
var
frmMain: TfrmMain;
implementation
uses
Check;
{$R *.dfm}
procedure TfrmMain.CheckSystem;
begin
TCheckDevices.Check;
TCheckHardware.Check;
TCheckMultiData.Check;
end;
procedure TfrmMain.Button1Click(Sender: TObject);
begin
CheckSystem;
end;
-----------------Ende Unit Form-----------------------------------------
-----------------Anfang Unit Check--------------------------------------
unit Check;
interface
uses
SysUtils;
type
TCheck = class(TObject)
protected
class procedure InternalCheck; virtual; abstract;
public
class procedure Check;
end;
ECheckHardware = class(Exception);
TCheckHardware = class(TCheck)
protected
class procedure InternalCheck; override;
public
end;
ECheckMultiData = class(Exception);
TCheckMultiData = class(TCheck)
protected
class procedure InternalCheck; override;
public
end;
ECheckDevices = class(Exception);
TCheckDevices = class(TCheck)
protected
class procedure InternalCheck; override;
public
end;
THardwareExeptionHandler = class(TObject)
public
class procedure BehandleException(const AE: Exception);
end;
implementation
class procedure TCheckHardware.InternalCheck;
begin
if 1 <> 2 then //Pseudo-Überprüfung
raise ECheckHardware.Create('Fehler in der Hardware');
end;
class procedure TCheckMultiData.InternalCheck;
begin
if 1 <> 2 then //Pseudo-Überprüfung
raise ECheckMultiData.Create('Fehler im MultiDevice');
end;
class procedure TCheckDevices.InternalCheck;
begin
if 1 <> 2 then //Pseudo-Überprüfung
raise ECheckDevices.Create('Fehler im Device');
end;
class procedure THardwareExeptionHandler.BehandleException(const AE:
Exception);
begin
if AE.ClassType = ECheckHardware then
begin
asm
nop;
end; //irgendwas machen
end
else if AE.ClassType = ECheckDevices then
begin
asm
nop;
end; //irgendwas machen
end
else if AE.ClassType = ECheckMultiData then
begin
asm
nop;
end; //irgendwas machen
end
end;
class procedure TCheck.Check;
begin
try
InternalCheck;
except
on E: Exception do
THardwareExeptionHandler.BehandleException(E);
end;
end;
-----------------Ende Unit Check----------------------------------------
Klar, das mach ich auch nciht wenn ich zwei Zahlen auf > überprüfe, aber
wenn ich was richtiges Prüfe, so wie halt in diesem Beispiel Hardware
usw. dann darf es auch ruhig ne richtige Klasse sein. Klar, ist nen
bisschen mehr zu schreiben, aber dafür weiss jeder gleich wo sich das
prüfen befindet: TKLassename.Check
Deutlich wartbarer, auch nach Jahren, und jederzeit an jedem Ort
wiederverwendbar.
(Die Geschichte mit den Classfunctions ist jetzt auch eher aus
schreibfaulheit heraus entstanden, aber dürfte auch okay sein.)
--
Ciao,
Sven
Dem Sven sein Blog
www.EndeNeu.de - /The greatest thing, since bread came sliced/
-----BEGIN GEEK CODE BLOCK-----
Version: 3.12
GCS d- s:- a- C+++ UL--- P L+ E-- W++ N++ o++ K w+++
O- M- V-- PS++ PE Y PGP+ t 5-- X R- tv b+ DI++ D
G e h- r++ y+
------END GEEK CODE BLOCK------
.
- References:
- F: Repeat .... until-Schleifen
- From: Simon Schäberle
- Re: F: Repeat .... until-Schleifen
- From: Thomas G. Liesner
- Re: F: Repeat .... until-Schleifen
- From: Sherlock
- Re: F: Repeat .... until-Schleifen
- From: Erich Günthner
- Re: F: Repeat .... until-Schleifen
- From: Thomas G. Liesner
- Re: F: Repeat .... until-Schleifen
- From: Erich Günthner
- Re: F: Repeat .... until-Schleifen
- From: Sven Heising
- Re: F: Repeat .... until-Schleifen
- From: Erich Günthner
- F: Repeat .... until-Schleifen
- Prev by Date: Re: F: Repeat .... until-Schleifen
- Next by Date: Re: F: Repeat .... until-Schleifen
- Previous by thread: Re: F: Repeat .... until-Schleifen
- Next by thread: Re: F: Repeat .... until-Schleifen
- Index(es):
Relevant Pages
|