Frage

Lassen Sie mich zunächst sagen, dass ich diesen Ansatz nicht befürworten, aber ich sah es vor kurzem, und ich frage mich, ob es ein Name für sie war ich verwenden könnte, um die Schuldigen zu zeigen. So, hier geht.

Jetzt haben Sie eine Methode, und Sie möchten einen Wert zurückgeben. Sie auch wollen einen Fehlercode zurück. Natürlich sind Ausnahmen eine viel bessere Wahl, aber aus irgendeinem Grund, den Sie stattdessen einen Fehlercode soll. Denken Sie daran, ich bin Anwalt spielen Teufels hier. So erstellen Sie eine generische Klasse, wie folgt aus:

class FunctionResult<T>
{
    public T payload;
    public int result;
}

Und dann erklären, um Ihre Funktionen wie folgt aus:

FunctionResult<string> MyFunction()
{
    FunctionResult<string> result;
    //...

    return result;
}

Eine Variante dieses Muster ist eine ENUM für den Fehlercode anstelle einer Zeichenfolge zu verwenden. Nun, zurück zu meiner Frage: Gibt es einen Namen für diese, und wenn ja, was ist es,

?
War es hilfreich?

Lösung

Ich würde zustimmen, dass dies nicht ausdrücklich ein Antipattern ist. Es könnte ein Geruch sein, abhängig von der Nutzung. Es gibt Gründe, warum man möchte eigentlich keine Ausnahmen verwenden (zum Beispiel der Fehler zurückgegeben werden, sind nicht ‚außergewöhnlich‘, für den Anfang).

Es gibt Fälle, in denen Sie einen Service haben wollen zurückkehren ein gemeinsames Modell für die Ergebnisse, einschließlich sowohl Fehler und gute Werte. Dies kann durch einen niedrigen Level Service Interaktion gewickelt werden, die das Ergebnis in eine Ausnahme oder andere Fehlerstruktur übersetzt, sondern auf der Ebene des Dienstes, lässt sie den Service Rückkehr ein Ergebnis und einen Statuscode ohne irgendeine Ausnahme Struktur zu definieren, die das könnte hat über eine Remote-Grenze übersetzt werden.

Dieser Code kann nicht unbedingt ein Fehler sein, entweder:. Sehen Sie eine HTTP-Antwort, die aus einer Menge unterschiedlicher Daten besteht, einschließlich einem Statuscode, zusammen mit dem Körper der Antwort

Andere Tipps

Es heißt " Fehlercode mit Ausnahme Ersetzen Sie"

Nun, es ist nicht ein Antipattern. Die C ++ Standard-Bibliothek nutzt diese Funktion und .NET bietet sogar eine spezielle FunctionResult Klasse in dem .NET-Framework. Es ist Nullable genannt. Ja, das ist nicht funktionieren Ergebnisse beschränkt, sondern es kann für solche Fälle verwendet werden und ist hier tatsächlich sehr nützlich. Wenn .NET 1.0 hatte bereits die Nullable Klasse, wäre es sicherlich für die NumberType.TryParse Methoden verwendet wurden, anstelle des out Parameter.

Ich gehe in der Regel die Nutzlast als (nicht const) Referenz und den Fehlercode als Rückgabewert.

Ich bin ein Spieleentwickler, wir Ausnahmen verbannen

Konrad ist richtig, C # verwendet Dual Return ganze Zeit Werte. Aber ich mag die TryParse, Dictionary.TryGetValue usw. Methoden in C #.

int value;
if (int.TryParse("123", out value)) {
    // use value
}

statt

int? value = int.TryParse("123");
if (value != null) {
    // use value
}

... vor allem, weil die Nullable Muster Nicht-Wert Rückgabetypen skaliert nicht auf (das heißt Klasseninstanzen). Dies wäre nicht mit Dictionary.TryGetValue arbeiten (). Und TryGetValue ist sowohl schöner als ein KeyNotFoundException (keine „erste Chance Ausnahmen“ ständig im Debugger, wohl effiziente), schöner als Java Praxis von get () Rückkehr null (was ist, wenn NULL-Werte zu erwarten sind), und effizienter als mit zu rufen ContainsKey () aus.

Aber das ist noch ein wenig verrückt - da dies wie C # sieht, dann sollte es ein out-Parameter verwenden. Alle Effizienzgewinne sind wahrscheinlich verloren durch die Klasse instanziieren.

(Könnte Java sein mit Ausnahme der „string“ Art in Klein zu sein. In Java natürlich müssen Sie eine Klasse verwenden, um Dual-Rückgabewerte zu emulieren.)

Ich bin nicht sicher, ob dies ist ein Anti-Muster. Ich habe häufig diese anstelle von Ausnahmen aus Gründen der Performance verwendet gesehen, oder vielleicht die Tatsache, dass das Verfahren noch deutlicher ausfallen kann. Mir scheint es eine persönliche Präferenz zu sein, anstatt ein anti-Muster.

ich mit denjenigen überein, die sagen, dass dies nicht ein Anti-Muster. Es ist ein absolut gültige Muster in bestimmten Kontexten. Ausnahmen sind für außergewöhnliche Situationen, Rückgabewerte (wie in Ihrem Beispiel) sollten in erwarteten Situationen verwendet werden. Einige Domains erwarten gültige und ungültige Ergebnisse von Klassen, und keiner von denen sind als Ausnahmen modelliert werden.

Zum Beispiel gegeben X Gasmenge kann ein Auto von A nach B zu bekommen, und wenn ja, wie viel Gas übrig geblieben ist? Diese Art von Frage ist ideal für die Datenstruktur, die Sie zur Verfügung gestellt. Nicht in der Lage, die Fahrt von A nach B zu machen, ist zu erwarten, daher sollte eine Ausnahme nicht verwendet werden.

Dieser Ansatz ist eigentlich viel besser als einige andere, die ich gesehen habe. Einige Funktionen in C, zum Beispiel, wenn sie einen Fehler stoßen sie zurückkehren und scheinen erfolgreich zu sein. Der einzige Weg, zu sagen, dass sie es versäumt ist, eine Funktion aufzurufen, die die neueste Fehlermeldung angezeigt wird.

Ich verbrachte Stunden zu debuggen Semaphore Code auf meinem MacBook versuchen, bevor ich herausgefunden habe, dass endlich sem_init nicht auf OSX funktioniert! Es ohne Fehler kompiliert und lief ohne Fehler verursacht - noch die Semaphore hat nicht funktioniert und ich konnte nicht herausfinden, warum. Ich habe Mitleid mit den Menschen, dass der Port eine Anwendung, die POSIX Semaphore OSX und mit Ressourcenkonflikten Fragen befassen müssen, die bereits ausgetestet wurden.

Wie wäre es die „weiß nicht, ob dies ein Fehler ist oder nicht“ -Muster. Scheint, wie wenn man wirklich eine Ausnahme hat, wollte aber ein Teilergebnis zurück, das Ergebnis in der Ausnahme wickeln würde.

Wenn Sie keine Ausnahmen verwenden möchten, die sauberste Weg, es zu tun ist, die Funktion zu haben, zurückgeben den Fehler / Erfolgscode und entweder einen Verweis oder Zeiger Argument, mit dem Ergebnis, wird ausgefüllt.

Ich würde es nicht ein Anti-Muster. Es ist ein sehr gut bewährt tragfähige Methode, die Verwendung von Ausnahmen oft vorzuziehen ist.

Wenn Sie Ihre Methode erwarten gelegentlich fehlschlagen, aber nicht berücksichtigen, dass außergewöhnliche, ziehe ich dieses Muster wie in .NET Framework verwendet:

bool TryMyFunction(out FunctionResult result){    

     //...    
     result = new FunctionResult();
}

Debatten über Gerüche und anti-Muster erinnern mich die „Survivor“ TV-Shows, wo man verschiedene Programmierkonstrukte haben versucht, die Insel einander ab zu stimmen. Ich würde es vorziehen, „konstruieren X hat so und so Vor- und Nachteile“, anstatt eine sich ständig weiterentwickelnden Liste der Edikte zu sehen, was sollte und sollte nicht durchgeführt werden.

Zur Verteidigung der anti-Muster Bezeichnung, dieser Code eignet sich für in ein paar Möglichkeiten verwendet werden:

  1. Objekt x = MyFunction () Nutzlast. (das Rückergebnis zu ignorieren - sehr schlecht)
  2. int code = MyFunction () zur Folge hat. (wirft die Nutzlast weg -. In Ordnung sein, wenn, dass die beabsichtigte Verwendung ist)
  3. Funktionsergebnis x = MyFunction (); // ... (ein Bündel von zusätzlichen Funktionsergebnis Objekten und zusätzlichen Code, sie alle über den Ort zu überprüfen)

Wenn Sie Rückgabecodes verwenden müssen, das ist in Ordnung. Aber dann Rückgabecodes verwenden. Versuchen Sie nicht, eine zusätzliche Nutzlast in damit zu packen. Das ist, was ref und aus Parameter (C #) für sich. Nullable-Typen könnten eine Ausnahme sein, aber nur, weil es zusätzlicher Zucker in der Sprache gebacken, sie zu unterstützen.

Wenn Sie immer noch mit dieser Einschätzung nicht einverstanden ist, downvote diese Antwort (nicht die ganze Frage). Wenn Sie denken, Sie ist es ein Anti-Muster, upvote es dann. Wir werden diese Antwort, um zu sehen, was die Gemeinschaft denkt.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top