web-dev-qa-db-ja.com

ハードコードされたif-then-elseに対するルールエンジンの提案

同じトピックについて 前の投稿 として質問を再投稿することは明確ではありませんでした。

現在、金融アプリケーションはクライアントからcsv形式で複数のフィードを受信して​​います。通常、データの行数は10万から500万です。この情報が処理されると、データを充実させて保存する必要があり、さまざまなルックアップが実行されます。データに基づいて、さらに値を分類または割り当てる必要があります。

マッピングの例は以下のようになります、

Firm     Category   Sub-Category   Code   Acct   = InternalCode( Enriched )
A         a1        sc1            c1     acc1   =   ACCT1
B                                         acc2   =   ACCT2
B         b1                                     =   ACCT3
B         b1        sc3            c3     acc4   =   ACCT4

ここで(データフィードから)、firm = Bおよびcategory = b1の場合、InternalCodeはACCT3であり、firm = BおよびAcct = acc2の場合、InternalCodeはACCT2です。

現在、これらはすべて、さまざまなプログラムでハードコード化されており、重複があり、維持/技術的負債が難しい。ハードコーディングを構成可能な方法で削除する必要があります。

多くのそのようなルックアップが発生しており、各ルックアップには数百のそのようなビジネスルールがあります。

ハードコーディングを削除する最良の方法は何ですか?ルールエンジンの使用を検討していますが、このようなユースケースの1つを選択するために適用する基準がわかりません。また、この種のロジックをコードから移動する他の方法はありますか?

ありがとう。

1
akumar

最初にあなたの目標を実現することが重要だと思います-それは通常単に「より良い保守性」ではありません。ハードコードされたルールをコードから構成に削除する背後にある一般的な動機は、多くの場合、開発者チームからビジネスチームにルールを維持する責任をシフトすることです(これもあなたのケースだと思います)。

つまり、一部の構成ファイルでのルールの構成と保守は、コードでのルールの実装ほど複雑ではなく、ビジネスチームの一部の人が実行できるようにする必要があります。そうでなければ、構成可能なソリューションはあなたに何の利益ももたらしません。

残念ながら、これに対する「1つのサイズですべてに対応する」ソリューションはほとんどありません。おそらく多くの異なるユースケースがあり、それぞれに異なるレベルの複雑さが必要です。 さまざまな方法を試してみて、簡単な方法から始めて、それがどれだけうまく機能するかを確認することをお勧めします。ここにいくつかのアイデアがあります

  1. 場合によっては、例に示すような決定表を使用するだけで、構成として十分な場合があります。テーブルをスプレッドシートまたはデータベースに入れ(ビジネスチームが好むものを選択)、テーブルを評価し、それらのルールに従ってデータを処理するプログラムを記述します。

  2. 場合によっては、独自のドメイン固有言語を実装するのが賢明かもしれません。これは非常に単純な場合もあれば、他の本格的なプログラミング言語のように複雑な場合もあります。 (たとえば、これは表形式を使用して数回実行しました。前提条件の列、アクションの列、およびパラメーターの列を使用しています。これは非常に単純なアプローチであり、実装は簡単ですが、多くの場合には十分強力です。)次に、DSLのインタープリターを実装できます。 DSLは、ビジネスパーソン(または少なくとも一部の「パワーユーザー」)がDSLを処理できるように、シンプルさを保つ必要があることに注意してください。

    別の例を挙げましょう。私はかつて開発者ではないユーザーがいましたが、SQLの経験がありました。彼らは100を超える検証ルールを備えたデータベースの検証ツールを必要としており、それらを自分で管理したいと考えていました。データモデルは非常に不可解ですが、ビジネスチームはその意味をよく理解しており、開発チームの他の誰よりも優れています。私たちは、それらを自分でSELECTステートメントに関連する部分を格納できるExcelシートにし、さまざまな方法で結果セットを処理するための「DSL」のようなものを定義しました。私たちに提供したプログラムはSQLを読み取り、DBに対して実行し、DSLに従って結果を解釈しました。このソリューションは、何年にもわたってまだ運用中であり、開発者のメンテナンス要件はありません。

  3. ルールエンジンの使用。これは、ルールを維持するための「事前定義された汎用DSL」の一種です。それはあなたのケースにとって良い解決策かもしれませんが、ルールを書いて維持するための専門家を必要とし、現在のシステムよりも維持とデバッグが難しいソリューションで終わるというリスクもあります)。 この古いSO質問 "ルールエンジンを使用するべきではないのはいつですか?" に対するすべての回答を確認し、pro引数とcon引数のどちらを確認することをお勧めしますあなたの特定の状況に適用されます。

1
Doc Brown

間違った方法

すべての関連フィールドを提供することで、データベーステーブルとクエリに各マッピングを配置するように指示するのは魅力的です。ただし、これは、ルールが部分一致に基づいている可能性があり、複数の一致ルールが見つかった場合、より具体的なルールが適用されるという事実を見逃します。

例:

Input data:                                  Output Explanations on rules

Firm     Category   Sub-Category   Code
B        b1         sc2            c3        ACCT3  (R2,R3 match but R3 is the most specific)
B        b1         sc3            c3        ACCT4  (R2,R3,R4 matches but R4 is the most specific) 
B        b2         sc3            c3        ACCT2  (only R2 matches, for B)

解決策1:各マッピングの高度なマッチングアルゴリズム

もちろん、ルールの優先順位の値を追加してマッピングテーブルを詳しく説明し、すべての候補を見つけて最も優先順位の高い候補を取得する、より複雑なクエリを生成することもできます。

これはエラーが発生しやすい(複雑なクエリ生成、予期しないルールが選択されるリスク、優先順位を手動で定義する必要がある)。さらに、それは多くの高価なクエリにつながる可能性があります。

解決策2:逐次マッピングを使用したマッチングアルゴリズム

別のアプローチとしては、一連のマッピングテーブルを決定し、ルールエンジンに連続する条件を反復させ、一致するルールが見つかるたびに停止する方法があります。

Mapping 1:  
Firm     Category   Sub-Category   Code   Acct   = InternalCode( Enriched )
A         a1        sc1            c1     acc1   =   ACCT1
B         b1        sc3            c3     acc4   =   ACCT4

Mapping 2:  
Firm     Category                                = InternalCode( Enriched )
B         b1                                     =   ACCT3

Mapping 3
Firm                                             = InternalCode( Enriched )
B                                         acc2   =   ACCT2

この種のアプローチは、高性能の価格設定エンジンで使用されています(そして 特許訴訟 とさえ呼ばれ、それはよく知られたアプローチであると結論しました:免責事項:弁護士、それは私の個人的な理解であり、法的助言ではありません)。

このアプローチは、レコードごとに(各レコードのマッピングの各セットを経由して)使用できます。ただし、CSVをデータベースにアップロードし、前の手順で既に入力されているアカウント値を更新しないいくつかの連続する更新ステートメントを使用すると、より効率的な方法で使用することもできます。

その他の解決策

別のアプローチとして、より洗練された ルールエンジン を使用し、すべてのif-then-elseをビジネスルールに変換することができます。利点は、これまでのようにマッピングテーブルを決定する必要がないことです。マッピングの依存関係を考える必要はありません(たとえば、ogfでマッピングフィールドが実際に以前のマッピングによって決定される場合)。新しいルールを追加するのも簡単です。

不便な点は、CSVレコードごとにルールエンジンが呼び出されることです。したがって、テーブルベースのアプローチよりも重いかもしれません(ソリューション2を参照)。また、ルール作成者が異なる種類のルール間の相互作用を理解することは困難です。

既存のルールベースのエンジンを使用せずに独自のエンジンを開発したい場合は、これに興味があるかもしれません SEの質問

0
Christophe