1
手短に言うと...

クライアント (REST などの「サービス コンシューマー」のようなクライアント) に、ビジネス レイヤーが何を実行したか、何を実行できなかったかに関するステータス情報を取得してもらいたいと考えています。null オブジェクトまたは単に null を返すだけでは、あまり説明的ではありません。何かあったかもしれません。

くそー-問題を説明するためにとても素敵なUMLシーケンス図を作成しましたが、評判ポイントが不十分なため、StackOverflowはそれを投稿できません:'(

問題はおそらく世界で最も古いものです。しかし、私はそれに対する満足のいく答えを見つけられませんでした。ここで説明されているソリューションに落ち着くことができましたMVPを使用して、サービス層のメッセージ/エラーを上位層にどのように伝達しますか? しかし、ループを飛び越えることはありません。いたるところに例外をスローすることは、良いことのようには思えません。結局、例外は高価です。また、非常に多くの「これが発生する可能性がある」シナリオに対して例外を作成する必要があります。

****質問は...「一般的な戻り値」を設計しますか、それとも例外をスローしますか?****
残念ながら、これまでのところそれに対する答えが見つかりませんでした...これがあなたの出番です: )

先に進み、ステータス コード、メッセージ、およびタイプ T の実際に要求された情報をその中に入れます。この一般的な戻り値が「ServiceResult」であるとしましょう。

私が行った考慮事項:

  • わかりましたので、私のビジネス層メソッドはすべて ServiceResult オブジェクトを返します。良い。
  • これは非常に簡単に操作できます。ただし、すべてのビジネス レイヤー マジックが、呼び出した 1 つのパブリック メソッドで発生します。そうではありません。通常ではありません。
  • そのため、ServiceResult をすべてのプライベート メソッドからもアクセスできるようにするか、パラメーターとして渡す必要があります。あなたはそれを100回渡したくありません...私を信じてください。
  • それが、「制御」ビジネス クラスに ServiceResult プロパティを追加することにしたときです。しかし、待ってください.. C# ではジェネリック プロパティを追加しません。サポートされている機能ではないためです。
  • 次は何ですか?代わりに「オブジェクト」をプロパティとして使用しますか? ほとんど... あなたは常にキャストしたくないし、そもそも何にキャストすればよいか分からないでしょう。T は何でもかまいません。そして、プライベート メソッド (最初に呼び出したパブリック メソッドから 3 レベル下) は単に型を認識していません。もちろん、それをクラスのプロパティにすることもできます。相変わらずデザインが悪いな・・・。
  • その問題を解決したと仮定すると、ServiceResult がまだ「障害」状態になく、それ以上の処理が役に立たない場合、次のメソッドが呼び出される前に毎回 ServiceResult.Status を確認する必要があります。もちろん、すべての魔法を Run(Func func) メソッドに入れることもできますが、この時点で... 遅くとも... 再び例外の使用を検討し始める場合:)

基本的にそれが、人々が例外をスローし、最高レベルで(コントローラーではなくビジネスロジック内で)キャッチするだけだと思う​​理由です。

私が認識していないこの問題の設計パターンはありますか?

4

1 に答える 1

3

いたるところに例外をスローすることは、良いことのようには思えません。

もちろん違います。何か例外的なことが起こったときに例外をスローします。例: メソッドを呼び出すとRepository.UpdateUser(var user)、ユーザー オブジェクトが期待され、指定された Id が取得されます (他にどのように更新できますか)。

そうでない場合は、メソッド コントラクトが守られていないため、例外をスローする必要があります。例外をスローすることで、開発者は例外を防ぐための措置を講じることも強制されます。たとえば、ユーザー オブジェクトが有効であることを確認します。

結局、例外は高価です。

それほど高価ではありません。例外パフォーマンス ヒットを補うために新しいハードウェアを購入するよりも、適切なサニティ チェックを行わないアプリケーションをデバッグする方がおそらくはるかに費用がかかります。(ほら、ばかげているように聞こえます。例外が全体的なパフォーマンスにそれほど影響を与える可能性は低いからです)。

また、非常に多くの「これが発生する可能性がある」シナリオに対して例外を作成する必要があります。

いいえ。これらの状況を処理できないメソッドを呼び出す前に、これらの「これが発生する可能性がある」シナリオを処理することを確認する必要があります。

問題は...「一般的な戻り値」を設計するか、例外をスローするかです。

一般的な戻り値は、ほとんどの場合価値がありません。戻り値を無視する怠惰な開発者は、休眠中のバグを導入する可能性があり、それは後で表面化し、数時間のデバッグが必要になります。

代わりに、エラーを予期するか、例外をスローするメソッドを設計します。とを比較int.TryParseしてくださいint.Parse。最初のものは失敗する可能性があることを示していますが(試行中のため)、もう一方は値が整数であることを期待しています(したがって、そうでない場合は約束どおりに完了できないため、例外がスローされます)。

于 2013-02-19T14:13:17.873 に答える