意図を抽象化して、それがどのように実装されているか、またはソースコードがどのように構成されているかが問題にならないようにします。基本的なレベルでは、失敗の説明のコレクションを生成するチェッカーのコレクションがあります。
疑似コードは基本的に次のようになります。
let reasons be a new, empty collection of failure reasons
let checkers be the list of relevant checkers
for each checker in checkers
if checker passes, continue
if checker fails, add explanation to reasons
if number of reasons is zero,
voucher is valid, success
if number of reasons > zero,
the voucher is invalid, format each element in reasons for display to the user
このロジックが整っていれば、リスト内のコードのこの部分によってチェッカーを取得できる限り、チェッカーがどのように構成されていてもかまいません。1 つのメソッドに多くのチェックを行うことができ、多くの理由が追加される可能性があります。チェッカーのリストにそれぞれのインスタンスを 1 つずつ含めて、多くのクラスを作成できます。重要なのは、実際のチェッカーがこのロジックから切り離されており、いつでも異なるチェッカーを使用できることです (ビジネス ルールの変更や、異なる地域での異なるルールを考えてみてください)。
言語によっては、少なくとも、チェッカーに使用される型を抽象化する必要があります。
それから始めましょう。同一のデータベース クエリが見つかった場合は、チェッカーのコレクションを実行するためのキャッシュの検討を開始します。
チェッカーがソース レベルでどのように構成されているかについては、問題ではありません。抽象化のみが行います。隠れることができるレベルの抽象化を提供すると、詳細はかなり柔軟になります。
長所:
- チェックを実行するビットは、実際の具体的なチェック (ビジネス ルールに基づいて変更される可能性があります) を気にしません。
- チェッカーは、1 つのソース ファイルでまとめて定義するか、他のスキームに基づいて分散させるなど、自由に編成できます。また、テスト用に単一のチェッカーを自由に分離することもできます。
- コレクションときれいな書式設定は、チェックの種類や数に関係なく、一度だけ実装する必要があります。
短所:
- 抽象化を適切に設計するには、事前に時間がかかります。これはおそらく後で報われるでしょう。
- 間接的なレイヤーがあり、理解しにくく、実際に行われているチェックを追跡するのが難しくなる場合があります。柔軟性は、理解の妨げになります。これらは、シナリオで考慮する必要があるものです。私の意見では、バウチャーのルールは時間の経過とともに変化する可能性があり、ここでの抽象化は理解するのが難しくないので、価値があると言えます.
Java で例を書くのに時間を費やしましたが、実際にはあまり役に立ちませんでした。抽象化の観点から考えようとすると、実際のメカニズムはそれほど重要ではなくなります。