19

私はこのアプローチを支持していませんが、最近それを見て、有罪の当事者を指すために使用できる名前があるかどうか疑問に思いました。だからここに行きます。

これでメソッドができたので、値を返したいと思います。また、エラーコードを返したいと思います。もちろん、例外の方がはるかに良い選択ですが、何らかの理由で代わりにエラーコードが必要です。ここで悪魔の代弁者を演じていることを忘れないでください。したがって、次のようなジェネリッククラスを作成します。

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

そして、次のように関数を宣言します。

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

    return result;
}

このパターンのバリエーションの1つは、文字列の代わりにエラーコードに列挙型を使用することです。さて、私の質問に戻りましょう。これには名前がありますか?もしそうなら、それは何ですか?

4

13 に答える 13

17

これは特にアンチパターンではないことに同意します。使い方によってはにおいがする場合があります。実際に例外を使用したくない理由があります (たとえば、最初に返されるエラーは「例外的」ではありません)。

エラーと適切な値の両方を含む、サービスがその結果に対して共通のモデルを返すようにしたい場合があります。これは、結果を例外またはその他のエラー構造に変換する低レベルのサービス インタラクションによってラップされる場合がありますが、サービスのレベルでは、例外構造を定義する必要なく、サービスが結果とステータス コードを返すことができます。リモート境界を越えて変換する必要があります。

このコードも、必ずしもエラーであるとは限りません。HTTP 応答を考えてみてください。HTTP 応答は、応答の本文と共に、ステータス コードを含むさまざまなデータで構成されています。

于 2008-09-16T14:29:08.450 に答える
12

「エラーコードを例外に置き換える」と呼ばれます

于 2008-09-16T14:22:29.247 に答える
10

まあ、それはアンチパターンではありません。C++ 標準ライブラリはこの機能を利用してFunctionResultおり、.NET は .NET フレームワークで特別なクラスを提供しています。と呼ばれていNullableます。はい、これは関数の結果に限定されませんが、そのような場合に使用でき、実際にここで非常に役立ちます。.NET 1.0 に既にNullableクラスがあった場合、それはパラメーターNumberType.TryParseではなくメソッドに使用されていたはずです。out

于 2008-09-16T14:23:16.623 に答える
6

通常、ペイロードを (const ではなく) 参照として渡し、エラー コードを戻り値として渡します。

私はゲーム開発者です。例外を追放します

于 2008-09-16T14:28:13.133 に答える
5

Konrad の言うとおりです。C# は常に二重の戻り値を使用します。しかし、私はC#のTryParse、Dictionary.TryGetValueなどのメソッドが好きです。

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

それ以外の

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

...ほとんどの場合、Nullable パターンは値以外の戻り値の型 (つまり、クラス インスタンス) にスケーリングされないためです。これは Dictionary.TryGetValue() では機能しません。また、TryGetValue は、KeyNotFoundException (デバッガーで常に「最初の例外」が発生しないため、間違いなく効率的) よりも優れており、null を返す Java の get() の慣行 (null 値が予期される場合) よりも優れており、必要な場合よりも効率的です。最初に ContainsKey() を呼び出します。

しかし、これまだ少し厄介です。これは C# のように見えるため、out パラメーターを使用する必要があります。クラスをインスタンス化することで、すべての効率向上が失われる可能性があります。

(「文字列」型が小文字であることを除いて、Java である可能性があります。もちろん、Java では、二重の戻り値をエミュレートするためにクラスを使用する必要があります。)

于 2008-09-16T14:36:59.837 に答える
4

これがアンチパターンかどうかはわかりません。私は一般的に、パフォーマンス上の理由から、またはおそらくメソッドがより明示的に失敗する可能性があるという事実を作るために、例外の代わりにこれが使用されるのを見てきました。私には、それはアンチパターンというよりも個人的な好みのようです。

于 2008-09-16T14:19:34.433 に答える
3

これはアンチパターンではないと言う人たちに同意します。特定のコンテキストでは完全に有効なパターンです。例外は例外的な状況のためのものであり、戻り値 (あなたの例のように) は予想される状況で使用する必要があります。一部のドメインは、クラスからの有効な結果と無効な結果を期待しており、それらのいずれも例外としてモデル化すべきではありません。

たとえば、X のガソリン量が与えられた場合、車は A から B まで移動できますか。そのような質問は、あなたが提供したデータ構造にとって理想的です。A から B への移動ができないことが予想されるため、例外を使用しないでください。

于 2008-09-16T15:39:02.243 に答える
2

このアプローチは、実際に私が見た他のいくつかのアプローチよりもはるかに優れています。たとえば、Cの一部の関数は、エラーが発生すると戻り、成功したように見えます。それらが失敗したことを知る唯一の方法は、最新のエラーを取得する関数を呼び出すことです。

sem_initがOSXで機能しないことにようやく気付く前に、MacBookでセマフォコードをデバッグするのに何時間も費やしました。エラーなしでコンパイルされ、エラーなしで実行されましたが、セマフォは機能せず、理由がわかりませんでした。POSIXセマフォを使用するアプリケーションをOSXに移植し、すでにデバッグされているリソース競合の問題に対処しなければならない人々を残念に思います。

于 2008-09-16T14:26:18.817 に答える
1

匂いとアンチパターンについての議論は、「サバイバー」のテレビ番組を思い起こさせます。そこでは、島から離れて互いに投票しようとするさまざまなプログラミング構造があります。私は、何をすべきか、何をすべきでないかの勅令の絶え間ないリストよりも、「コンストラクト X にはそれなりの長所と短所がある」ことを確認したいと考えています。

于 2008-11-19T00:31:49.647 に答える
1

「エラーかどうか判断できない」パターンはどうでしょうか。本当に例外があったが、部分的な結果を返したい場合は、結果を例外でラップするようです。

于 2008-09-16T14:13:51.747 に答える
1

例外を使用したくない場合、最もクリーンな方法は、関数にエラー/成功コードを返させ、結果で埋められる参照またはポインター引数を取ることです。

私はそれをアンチパターンとは呼びません。これは、例外を使用するよりも望ましいことが多い、非常によく証明された実行可能な方法です。

于 2008-09-16T14:34:09.187 に答える
1

メソッドがときどき失敗することが予想されるが、それが例外的であるとは考えない場合は、.NET Framework で使用される次のパターンをお勧めします。

bool TryMyFunction(out FunctionResult result){    

     //...    
     result = new FunctionResult();
}
于 2008-09-16T14:36:46.467 に答える
0

アンチパターンの指定を擁護するために、このコードはいくつかの方法で使用するのに適しています。

  1. オブジェクト x = MyFunction().payload; (返された結果を無視する - 非常に悪い)
  2. int コード = MyFunction().result; (ペイロードを捨てる - それが意図された用途であれば問題ないかもしれません。)
  3. FunctionResult x = MyFunction(); //... (一連の追加の FunctionResult オブジェクトと、それらをあらゆる場所でチェックするための追加のコード)

リターン コードを使用する必要がある場合は、それで問題ありません。ただし、リターン コードを使用します。余分なペイロードを詰め込もうとしないでください。それがrefおよびoutパラメーター (C#) の目的です。Null 許容型は例外かもしれませんが、それをサポートするための余分な砂糖が言語に組み込まれているためです。

それでもこの評価に同意できない場合は、この回答に反対票を投じてください (質問全体ではありません)。それがアンチパターンだと思うなら、賛成してください。この回答を使用して、コミュニティの意見を確認します。

于 2008-09-16T17:03:56.690 に答える