回答:
例外を使用して個々のビジネスルールチェックを表すことを意味する場合、それは非常に良い考えだとは思いません。多くの場合、複数の失敗した状態を報告する必要があり、最初の状態で停止することはありません。
一方、私がチェックすることを信じていないすべてのルールや、その後の要約で例外をスローすることをお勧めします。
あなたが私たちに与えた例では、例外を上げることは悪い考えだと思います。ユーザーが作業を開始する前に承認されていないことがわかっていても、ユーザーが何らかの機能を実行できるようにし、既にタスクを完了した後にメッセージを叩くことができる場合、それは悪い設計です。
例外を使用してビジネスルールを実施することは、適切な設計ではありません。
優れたビジネスロジックを作成する上で、例外をスローすることの価値がわかりません。システムの運用における予期しない状況に対処することを目的としたシステムの使用を伴わないビジネスロジックの処理には、多数のアプローチがあります。
ビジネスロジックでは、条件が満たされないことが予想されます。それがそもそもそれを持っている理由であり、予期しないI / Oエラー、メモリ不足エラー、null参照を処理するのと同じメカニズムに便乗したくありません。これらはシステムの障害ですが、満たされていないビジネス条件を検出することは、システムの正常な動作です。
さらに、意図しない結果が発生する可能性のあるシステムです。ある時点で例外をキャッチする必要があるため、意図しない場所でキャッチされる新しいビジネスルールの例外が発生したり、実際に意図されていない例外をキャッチするビジネスルールを探すコードが見つかる可能性がありますそれのための。はい、これらの条件は優れたコーディング慣行で説明できますが、複数の開発者が作業している自明ではないシステムでは、間違いが発生するため、コストのかかる間違いではないことを期待する必要があります。
ビジネスルールを表現することと実装することは別です
ユーザーエクスペリエンスについて考えます。ユーザーが営業担当者ではない場合、「請求書を作成する」というボタンをすべて提供するのはなぜですか?
それは完全に何が行われているかに依存します。
まず、あなたが望む実際の動作は何ですか?誰かが自分の情報を入力している場合、拒否と、基本的に「それはできません」というダイアログボックスが正しいでしょう。これがデータ入力者であり、フォームの山から作業している場合、ダイアログボックスもおそらく適切であり、データ入力者は無効なフォームを特別な山に入れることができます。バッチ処理を実行している場合、物事を停止させるのではなく、フラグを立てて次の処理に進みます。
動作を取得したら、それをどのように実装するかを決定する必要があります。例外をスローするビジネスルールチェッカーを使用することをお勧めします。戻りコードを返し、それを引き継ぐことは、間違った方向に進む可能性のある何かであり、間違いのあるエントリがさらに先に進むことは望ましくありません。
パフォーマンスの費用を心配しないでください。個人がデータを入力する場合、関連する他の時間と比較して簡単です。通常、人間はそのシステムで最も時間がかかります。バッチジョブの場合、例外がパフォーマンスの問題である場合、非常に多くの不良レコードを入力していることになり、実際にはそれらすべてを処理および再入力することは、例外よりも多くの問題になります。
一貫性のある堅牢で適切に設計された例外APIを持つことは非常に適切です。これを使用してビジネスルールを適用することも適切です。実際、私の経験では、ビジネスルールが複雑になるほど、この方法で処理される可能性が高くなります。権限のある分岐ロジックを作成するよりも、例外が予想されるシステムを作成する方が簡単ではないにしても、同じくらい簡単です。
これは、単一の文で記述できる単純なルールは、一般に、それがどれであるかに応じて、予防的または信頼できる方法で実装されるべきだということです。ただし、多次元であり、3つまたは4つ以上の要因を必要とするルールがある場合(特に、これらの要因の選択が1つ以上の他の要因に基づいている場合)、例外のコーディングはより保守可能です。多くの場合、これらの場合、ロジックパスにはスローする必要がある多くの前兆例外があります(アクションを実行できない理由をチェックします)(またはその逆)セキュリティへのフォールスルーがあります(アクションが許可されていることをチェックします) )、チェックする必要がある信頼できる累積ロジックがいくつかある場合があります(子孫/祖先の可用性、オブジェクトを入れる必要があることを示す前駆体の状態など)。
このタイプの例外のスローから得られる利点の1つは、プロジェクトの複数の領域で前駆体例外を分離して再利用できることです。(これがアスペクト指向プログラミングの本質です。)これを行うことにより、自己完結型の保守可能なコンポーネントに一般的なビジネスルールの特定の側面をカプセル化できます。一般に、これらのコンポーネントは、スローされるエラーメッセージと1-1で対応します。(時には、いくつかの異なる例外をスローする1つのコンポーネントがありますが、複数のコンポーネントから同じ例外がスローされることはほとんどありません。)
私の意見では、例外ベースのシステムを設計することは難しく、最初の開発時間はNレベルすべてにわたって例外プロセスを構築する必要があるため、より長くなります。ただし、これらのシステムは一般的にはるかに安定しています。「失敗しない」システムを設計することは決してできませんが、例外ベースの設計の利点は、常に障害を予測していることです。ほとんどの人にとって、このプロセスは直感に反する可能性があります。それは、道順を尋ねて、誰かにあなたがオンにしてはいけないすべての道を教えてもらうようなものです。