Einzelnen Beitrag anzeigen

Benutzerbild von Sir Rufo
Sir Rufo

Registriert seit: 5. Jan 2005
Ort: Stadthagen
9.454 Beiträge
 
Delphi 10 Seattle Enterprise
 
#32

AW: Best Practice: Wann verwendet ihr Exceptions in Funktionen?

  Alt 11. Dez 2013, 08:46
In dem Beispiel fehlt noch die Behandlung welche Division fehlgeschlagen ist. Wie das da schön geht, erschließt sich mir nicht.
Es hindert dich ja auch niemand daran, das Nullobjekt um beliebige Fehlerinformationen zu erweitern. Dann könntest du in diesem Fall, wenn du das denn wölltest, sogar konkret speichern, dass der Fehler genau bei der x-ten Berechnung aufgetreten ist. Und dann hast du schonmal deutlich mehr Infos, als mit dem äquivalenten Exception-Code (wie von Furtbichler gezeigt).
Allerdings hätte ich das Object als NaNComputation deklariert, weil es für diesen konkreten Fall benutzt wird.

Ob man Exceptions oder NullObjekt verwendet, hängt eben davon ab, ob es eine Ausnahme (falscher Zugriff) oder gewöhnlicher Anwendungsfall ist.

Exception weil ich die Grenzen beachten muss
Delphi-Quellcode:
type
  TMyList = class
    property Count;
    property Items[Index : Integer] : TItem read GetItem;
  end;

function TMyList.GetItems(Index : Integer) : TItem;
begin
  if Index >= Count then
    raise Exception;
  Result := ...
end;
NullObjekt

Im Hauptmenü gibt es den Menü-Punkt Drucken aber das Drucken wird nicht an jeder Stelle unterstützt (weil da gibt es nichts zum Drucken oder ist noch nicht implementiert oder das Druckmodul wurde nicht gekauft).
Die Aktion aus dem Hauptmenü holt sich trotzdem mit CommandHandler.Command['print'] den Eintrag und bekommt eben mal ein echtes Objekt oder eben das NullObjekt.

Exceptions wären hier kontraproduktiv und eine Überprüfung von aussen macht die Verdrahtung aufwendiger. Hier kann jeder beliebige Befehl im Menü verdrahtet werden und die Implementierung kann erfolgen wann will.
Delphi-Quellcode:
ICommand = interface
  function CanExecute : Boolean;
  procedure Execute;
end;

TCommandHandler = class
  property Command[const Name : string] : ICommand read GetCommand;
end;

function TCommandHandler.GetCommand( const Name : string ) : ICommand;
begin
  if not FCommands.Contains( Name ) then
    Result := NullComand.Create
  else
    Result := FCommands[Name];
end;

NullCommand = class( TInterfacedObject, ICommand )
  function CanExecute : Boolean;
  procedure Execute;
end;

function NullCommand.CanExecute : Boolean
begin
  Result := False;
end;

procedure NullCommand.Execute;
begin
end;
Kaum macht man's richtig - schon funktioniert's
Zertifikat: Sir Rufo (Fingerprint: ‎ea 0a 4c 14 0d b6 3a a4 c1 c5 b9 dc 90 9d f0 e9 de 13 da 60)

Geändert von Sir Rufo (11. Dez 2013 um 08:48 Uhr)
  Mit Zitat antworten Zitat