Wenn es eine Methode gibt
bool DoStuff() {
try {
// doing stuff...
return true;
}
catch (SomeSpecificException ex) {
return false;
}
}
sollte es eher heißen IsStuffDone()
?
Beide Namen können vom Benutzer falsch interpretiert werden: Wenn der Name der DoStuff()
Grund ist, wird ein Boolescher Wert zurückgegeben? Wenn der Name ist IsStuffDone()
, ist nicht klar, ob die Methode eine Aufgabe ausführt oder nur ihr Ergebnis prüft.
Gibt es eine Konvention für diesen Fall? Oder ein alternativer Ansatz, da dieser als fehlerhaft gilt? Beispielsweise könnte in Sprachen mit Ausgabeparametern wie C # eine boolesche Statusvariable als eine an die Methode übergeben werden, und der Rückgabetyp der Methode wäre void
.
BEARBEITEN: In meinem speziellen Problem kann die Ausnahmebehandlung nicht direkt an den Aufrufer delegiert werden, da die Methode Teil einer Schnittstellenimplementierung ist. Daher kann der Aufrufer nicht mit der Behandlung aller Ausnahmen verschiedener Implementierungen beauftragt werden. Diese Ausnahmen sind nicht bekannt. Der Anrufer kann jedoch mit einer benutzerdefinierten Ausnahme umgehen, wie StuffHasNotBeenDoneForSomeReasonException
in der Antwort und im Kommentar von npinti vorgeschlagen .
quelle
boolean
es fast immer falsch ist, eine Ausnahme zurückzugeben, anstatt sie zu verpacken oder zu übergeben.BadlyDesignedMethodInSeriousNeedOfRefactoring
? Und um Ihre Frage zu den Ausnahmen zu beantworten: Ich würde sie entweder vom Anrufer behandeln lassen oder abfangen lassen und dann eine benutzerdefinierte Ausnahme auslösen, die bedeutet, dass "diese Methode ihre Aufgabe nicht erfüllt". Teile und genieße.if (FirstMethodSucceeds(problem) or SecondMethodSucceeds(problem) or ...) Hurray(); else UniversalSolve(problem);
. Dasselbe mit (benutzerdefinierten?) Ausnahmen zu tun, wäre sinnlos komplizierter.Antworten:
In .NET gibt es häufig Methodenpaare, von denen eine möglicherweise eine Ausnahme (
DoStuff
) auslöst und die andere einen Booleschen Status und bei erfolgreicher Ausführung das tatsächliche Ergebnis über einen out-Parameter (TryDoStuff
) zurückgibt .(Microsoft nennt dies das "Try-Parse-Muster" , da die
TryParse
Methoden verschiedener primitiver Typen möglicherweise das bekannteste Beispiel dafür sind .)Wenn das
Try
Präfix in Ihrer Sprache ungewöhnlich ist, sollten Sie es wahrscheinlich nicht verwenden.quelle
if (TryDoStuff()) print("Did stuff"); else print("Could not do stuff");
ist meiner Meinung nach eine ziemlich normale und intuitive Sprache.TryDoStuff
davon ausgegangen wird , dass Methoden fehlerfrei sind und keine Nebenwirkungen haben, wenn sie false zurückgeben.Remove
Methoden, die beispielsweise im .NET Framework ein Element aus einer Datenstruktur entfernen (z. B.Dictionary
) und a zurückgebenbool
. Der Benutzer der API kann entscheiden, ob er sie verwendet oder ignoriert. Fehler werden jedoch als Ausnahmen gemeldet.Was ist, wenn Sie einfach die Ausnahme zum aufrufenden Code geworfen haben?
Auf diese Weise delegieren Sie die Ausnahmebehandlung an denjenigen, der Ihren Code verwendet. Was ist, wenn Sie in Zukunft Folgendes tun möchten:
FileNotFoundException
geworfen wird, führen Sie Aktion B ausWenn Sie Ihre Ausnahme zurückwerfen, würde die obige Änderung einfach das Hinzufügen eines zusätzlichen
catch
Blocks bedeuten. Wenn Sie es so lassen, wie es ist, müssen Sie die Methode und den Ort, von dem aus die Methode aufgerufen wird, ändern. Dies kann sich je nach Komplexität des Projekts an mehreren Orten befinden.quelle
DoStuff
, dass ein Fehler auftritt, entspricht das Auslösen einer Ausnahme für den Fehlerfall dem Steuern des Programmflusses mit schlechten Ausnahmen. Ausnahmen haben auch einen inhärenten Leistungsaufwand. WennDoStuff
ein Fehler ein ungewöhnlicher Fall ist, sind Ausnahmen auf jeden Fall der richtige Weg, wie @npinti vorschlägt.DoStuff()
Methode bereinigt, nachdem der innere Code eine Ausnahme ausgelöst hat und die Post-Bedingungen der Methode noch immer korrekt sind, ist ein Rückkehrcode möglicherweise eine bessere Option, da der Fehler behoben wurde.DoStuff()
ist ausreichend, und der zurückgegebene Wert der Funktion sollte dokumentiert werden, und Sie müssen ihn nicht im Funktionsnamen erwähnen, um nach einer Vielzahl von verfügbaren APIs zu suchen:PHP
C-Sharp
quelle
In Java definiert die Collection- API eine Add-Methode , die einen Booleschen Wert zurückgibt. Grundsätzlich wird zurückgegeben, ob das Hinzufügen die Sammlung geändert hat. Für a
List
wird normalerweise true zurückgegeben, da das Element hinzugefügt wurde, während für aSet
false zurückgegeben werden kann, wenn das Element bereits vorhanden war, daSet
s jedes eindeutige Element höchstens einmal zulässt.Das heißt, wenn Sie ein Element hinzufügen, das von der Auflistung nicht zugelassen ist, z. B. einen Nullwert, wird beim Hinzufügen
NullPointerException
eher ein als ein False zurückgegeben.Warum müssen Sie einen Booleschen Wert zurückgeben, wenn Sie dieselbe Logik auf Ihren Fall anwenden? Wenn eine Ausnahme ausgeblendet werden soll, tun Sie dies nicht. Wirf einfach die Ausnahme. Auf diese Weise können Sie sehen, was schief gelaufen ist. Wenn Sie einen Booleschen Wert benötigen, weil dies möglicherweise aus einem anderen Grund als einer Ausnahme nicht erfolgt ist, benennen Sie die Methode
DoStuff()
, da dies das Verhalten darstellt. Es macht Sachen.quelle
Könnte aus verschiedenen Gründen fehlschlagen, Ausnahme, normale Bedingungen, so würde dies verwenden:
Wichtig ist zu dokumentieren, was der Boolesche Wert bedeutet.
quelle
Normalerweise habe ich Methoden, die ein
OperationResult
(oderOperationResult<T>
) zurückgeben und dieIsSuccess
Eigenschaft auf dasOperationResult
entsprechende setzen. Wenn die 'usual'-Methode ungültig ist, geben Sie zurückOperationResult
, wenn die' usual'-Methode ein Objekt zurückgibt, geben Sie zurückOperationResult<T>
und setzen Sie dieItem
Eigenschaft auf denOperationResult
entsprechenden Wert. Ich würde auch vorschlagen, MethodenOperationResult
wie.Failed(string reason)
und zu haben.Succeeded(T item)
.OperationResult
wird schnell zu einem vertrauten Typ in Ihren Systemen und Entwickler lernen, wie man damit umgeht.quelle
Es hängt wirklich von der Sprache ab, die Sie verwenden. Wie für einige Sprachen gibt es Konventionen und Protokolle, die in vielen Sprachen oder überhaupt nicht existieren.
In der Objective-C-Sprache und im iOS / Mac OS X SDK lauten die Methodennamen normalerweise:
Wie Sie sehen, gibt es dort eine Methode namens viewDidLoad. Ich bevorzuge diese Art der Benennung, wenn ich meine eigenen Anwendungen erstelle. Dies könnte verwendet werden, um zu überprüfen, ob etwas passieren sollte, wie Sie sagten. Ich glaube, dass Sie zu tief darüber nachdenken, wie Sie Ihre Methoden nennen. Die meisten Methoden geben den Status der von ihnen ausgeführten Aktionen zurück. Beispiel:
In PHP gibt mysql_connect () false zurück, wenn die Verbindung fehlschlägt. Es sagt nicht, dass es so sein wird, aber es tut es und die Dokumentation sagt, dass es so ist, dass es für den Programmierer nicht falsch interpretiert werden kann.
quelle
Ich möchte vorschlagen, das Präfix "Try" zu verwenden. Dies ist ein bekanntes Muster für Situationen, in denen die Methode erfolgreich ist oder nicht. Dieses Benennungsmuster wurde von Microsoft in .NET Framework verwendet (z. B. TryParseInt).
Aber vielleicht geht es hier nicht um Benennung. Es geht darum, wie Sie die Eingabe- / Ausgabeparameter Ihrer Methode entwerfen.
Meine Idee ist, dass, wenn eine Methode einen Rückgabewert hat, der Zweck des Aufrufs dieser Methode darin bestehen sollte, diesen Rückgabewert zu erhalten. Verwenden Sie daher keinen Rückgabetyp, um den Status einer Operation anzuzeigen.
In C # bevorzuge ich die Verwendung eines out-Parameters. Mit einem Out markiere ich den Parameter als Seitenparameter. Insbesondere unterstützt C # 6 die Inline-Variablendeklaration.
quelle
Ich würde einen Namen auswählen, der auf der primären Rolle der Methode basiert. Die Tatsache, dass diese Methode einen booleschen Wert zurückgibt, erfordert nicht das Präfix 'Is'. Lassen Sie uns etwas Java-Code haben, der das Präfix 'Is' ziemlich ausführlich verwendet. Schau es dir an
java.io.File.delete()
. Es kehrt zurückboolean
, wird aber nicht aufgerufenisFileDeleted()
. Der Grund ist, dass die Hauptaufgabe der Metode darin besteht, eine Datei zu löschen. Jemand ruft diese Methode mit der Absicht auf, eine Datei zu löschen.Der Boolesche Wert dient nur dazu, das Ergebnis der Arbeit wiederzugeben. Auf der anderen Seite wollen wir mal sehen
java.util.Map.isEmpty()
. Offensichtlich rufen Sie eine solche Methode auf, um herauszufinden, ob die Sammlung leer ist. Du willst keine Sachen machen. Sie möchten nur herausfinden, wie der aktuelle Status ist.Also persönlich würde ich definitiv dabei bleiben
DoStuff()
.Das ist für mich ein sehr wichtiges Thema. Oft stoße ich bei der Pflege von Legacy-Code auf etwas, das ich persönlich als "Lügenmethode" bezeichne. Der Name weist auf die Aktion A hin, der Body jedoch auf die Aktion B. Das bizarrste Beispiel ist eine Getter-Methode, mit der Daten in der Datenbank geändert werden.
quelle