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;