1.2. なぜルールエンジンを使うか
よく尋ねられる質問として、次のようなものがあります。
-
どんなときにルールエンジンを使うべきですか?
-
手で「if…..then」文のコーディングを行うアプローチに比べて、ルールエンジンにはどんなメリットがありますか?
-
なぜ、Beanshellのようなスクリプトのフレームワークを使わずにルールエンジンを使うべきなのですか?
以下でこれらに答えていこうと思います。
1.2.1. ルールエンジンのメリットの要約
宣言的プログラミング
ルールエンジンでは、「どのようにそれを行うか」を記述するのではなく「何を行うか」を宣言することでプログラムが作れます。このことは、難しい問題に対する解法を表現することを容易にし、結果として検証された解が得られる(ルールは、コードを追うよりも容易に読めます)ということを示しており、ルールエンジンのキーとなる特長となっています。
ルールシステムは、非常に難しい問題を解決する能力がある一方、なぜその決定がなされたかを説明できる解を得られます(ニューラルネットワークのような他のAIシステムでは、これはそう簡単ではありません。また、私の脳も、なぜ自動車の横に引っ掻き傷をつけたか自分ではわかりません)。
ロジックとデータの分離
データは、ドメインのオブジェクトの中にある一方、ロジックはルールの中にある・・・これはデータとロジックを一つにカップリングするというオブジェクト指向の原則を破っています(これは、視点の違いによってメリットにもなりうるし、デメリットにもなり得ます)。しかし結果として、ロジックはすべてルールにまとめてあるので将来的にロジックに変更がかかったときのメンテナンスがより簡単になります。
スピードとスケーラビリティ
Reteアルゴリズム、Leapsアルゴリズム、およびその派生であるDroolsのReteOO (とLeaps)は、対象となる領域のオブジェクトデータにルールパターンをマッチングさせる非常に効率的な方法を提供しています。これらは、(ルールエンジンが過去のマッチング状況を記憶しているので)データセットの変更が全体的に起こるのでない場合に特に効率的になります。
知識の集中化
ルールを用いることによって、実行可能な知識のリポジトリ(知識ベース)を作ることができます。このリポジトリは、たとえばビジネスポリシーに対して矛盾のない単一の基準となっていることを意味しており、さらに理想的には、ルールがとても読みやすく、ドキュメントとしても有効なものとなります。
ツールの統合
Eclipseのようなツール(そして将来的には、WebベースのUI)は、ルールを編集、管理する方法を提供し、即座にフィードバック、検証やコンテンツアシスタント機能を得る事ができます。また監査やデバッグのツールも利用できます。
説明機能
ルールシステムは、ルールエンジンによって、なされた「決定」をログに記録できること(また、なぜその決定がなされたか)によって、効率的に「説明機能」を提供します。
(ドメインの専門家でも読める)理解しやすいルール
対象となる問題領域をモデル化したオブジェクトモデル(やオプションの対象領域固有言語)を作ることで、ルールを自然言語にとても近い形で表現することができます。これによって、技術を持たないドメインの専門家でもロジックが理解できるようにできます。すべてのプログラムの裏方配管は、通常のコードの中に埋め込まれ、隠されます。
1.2.2. どんな場合にルールエンジンを使うべきか
この問いに対する最も短い答えは、「通常の(伝統的な)プログラミング手法では、問題に対する満足なアプローチが得られない場合」ということになります。この短い答えを聞くと、もっと説明が欲しいという方もおられるでしょう。「伝統的なアプローチではない」の意味するところは、おそらく次にあげるうちの一つでしょう:
-
通常のコードで記述するにはとても難しい問題
複雑なようには見えないが、かと言ってそれを脆弱で無い方法で構築する術を見出せないような問題 -
アルゴリズムが決まっている明らかな解法がないような問題
解法が複雑であり、伝統的な明らかな解法がなく、問題それ自身もよく理解されていないような問題 -
ロジックがしばしば変更される場合
ロジック自身は単純である(必ずしもそうである必要はないが)かもしれませんが、非常に頻繁にルールが変更される場合。多くの組織では、ソフトウェアのリリースはめったになく、その間隔も大きいものです。今日必要とされ期待される敏捷性(アジャイル性)を、安全な形で提供する上で、ルールは役に立つでしょう。 -
ドメインの専門家(またはビジネスアナリスト)が、協力できるが、技術者ではない場合。
技術者でないドメイン専門家が、ビジネスルールに関する知識を豊富に持っていることはよくあります。一般に彼らは技術を知りませんが、とても論理的でありえます。ルールは、彼らに自らのロジックを自分の言葉で表現することを可能にします。もちろん、彼ら専門家は、批判的に考える必要がありますし、論理的思考ができることを要求されます(「ソフト」な、技術者でない立場にいる多くの人は、そうではありません。そこで注意深く、ビジネス知識をルールにコード化することによって、現状存在するビジネスルールにある欠陥を白日の下にさらすことがよくあります)。
もちろん、ルールがプロジェクトチームの経験に照らして、新しい技術であるのなら、そのオーバヘッドを考慮に入れなければいけません。ルールは、自明の技術ではないですが、容易にすることはあります。
現在のオブジェクト指向アプリケーションにおいては、一般的にルールエンジンをビジネスロジック(もちろんそれは、アプリケーションによってその意味が違ってきますが)のキーとなる部分-特に現実に煩雑な部分-を含んでいるようにして使うでしょう。これは、ロジックをオブジェクトの内側にカプセル化しておくというオブジェクト指向の概念に反するものです。しかしこれは、オブジェクト指向の原理を投げ出すと言っているのではなく、反対にどんな現実世界のアプリケーションでもビジネスロジックがアプリケーションの1つのパートに過ぎないことを言っているのです。もし正しいとは思えないコードの中に、たくさんの”if” “else” “switch” や他の煩雑なロジックがあることに気づいたら(そして、間違いを作りこんだからか、ロジックや自分の理解に変更があったかにかかわらず、それを直したいと思ったとき)、ルールを使うことを考えて見ましょう。もし、解法のアルゴリズムやパターンが存在しないような難しい問題に直面したようなとき、ルールを考えて見ましょう。
ルールは、アプリの中に埋め込まれて使われるかも知れませんし、ひとつのサービスとして使われるかもしれません。しばしば、ルールはステートフルなコンポーネントとして扱うのがベストです。それゆえ、アプリケーションの統合された一部分となっています。しかしながら、ステートレスの再利用可能なルールサービスを作って成功しているケースもあります。
あなたの所属する組織の中では、開発中のシステムの中にルールを変更するためのプロセスを使う必要があるかどうかを考えることが重要です(ルールに代わるオプションはたくさんあります。しかし違う組織には違う要求があり、しばしばアプリケーションベンダーやプロジェクトチームのコントロールから逸脱してしまうことがあります)。
1.2.3. ルールエンジンを使うべきでない場合
Droolsのメーリングリストの常連であるDave Hameの言葉を引用すると、 「ルールエンジンを利用するというワクワクするような経験の中にいると、人は、ルールエンジンが複雑なアプリケーションやソリューションの単なる一つのピースであることを忘れてしまうように思えます。 ルールエンジンは実際、ワークフローやプロセスの実行を扱うことを目指しているわけでも、ルールを扱うために設計されたワークフローエンジンやプロセス管理ツールであるわけでもありません。仕事には、それに合ったツールを使うべきです。確かに切羽詰ったときにはペンチをハンマーの代わりに使うことはできるでしょう。でも、ペンチはそのために設計されたものではないのです。
ルールエンジンは、動的(ここで言う動的とは、ルールがデータとして保持、管理、更新できるという意味)なので、しばしばソフトウェアを配置(deploy)する問題に対してのソリューションとして考えられることがあります。もし、ルールエンジンを使いたい理由がそういったところにあるのであれば、ルールエンジンがもっとも威力を発揮するのは、プログラムが宣言的なルールのセットで書けたときであることに気付くべきです。ルールエンジンの代わりとして、ルックアップテーブルなどを用いたデータ指向設計や、書いたスクリプトがすぐに変更ができるようデータベースで管理されるようなスクリプト/プロセスエンジンを考慮に入れることもできます。
1.2.4. スクリプトまたはプロセスエンジン
ここまで述べてきたことで、どんなときにルールエンジンを使ってもよいかどうか説明できたことを望んでいます。
「急な変更」に対するダイナミックさを持ち合わせた代替手法としてはスクリプトベースのエンジンがあります(もっとも、他にも多くの手法があります)。
また、jBPMのような(ワークフローも可能な)プロセスエンジンもあり、プロセスのステップをグラフィカル(またはプログラム的)に表現することができます。 これらのステップは、意思決定のポイントを含むことがあり、それ自身簡単なルールとなります。プロセスエンジンとルールは、しばしばうまく協働して動き、それゆえそれらは排他的な関係というわけではありません。
ルールエンジンについて、注意しておくべきキーポイントがひとつあります。それは、実質的にはスクリプトエンジンであるようなルールエンジンがあるということです。スクリプトエンジンの短所は、アプリケーションがスクリプトに強く結びついてしまい(もしこれがルールであれば、ルールを効果的にダイレクトに呼べるのですが)、このことが、将来的なメンテナンスをより難しくさせる可能性があるということであり、また、時間とともに複雑さが増していきがちであるということです。スクリプトエンジンの長所としては、最初に実装するときはスクリプトの方がより簡便であり、早く結果が得られるということです(また、手続き型に慣れたプログラマーにとっては、考え方がより単純ですから!)
過去にアプリケーションの振る舞いを変更するメタデータが保持されたコントロールテーブルを持っているようなデータ指向のシステムを成功裡に実装したことのある方は多く、そして、それはそのコントロールが非常に限られた範囲でいる間は、よく機能するでしょう。 しかし、オリジナルの開発者のみがアプリケーションの振る舞いを変更できるというような場合、もし大幅な拡張をほどこしてしまうとこのようなシステムは簡単にコントロール不能なものとなったり、あまりにも制約が大きすぎる場合には、アプリケーションの成長を止めてしまうことにもつながります。
1.2.5. 強い結合と緩い結合
おそらく、システム設計において「密結合」、「疎結合(緩い結合)」というような言葉を聞いたことがあるでしょう。一般的に設計上の規約においては、柔軟性を与えるという理由から緩いあるいは「弱い」結合が望ましいとされています。ルールについても同様で、「強い結合」と「弱い結合」があります。この意味での強い結合とは、一つのルールが発火が、明らかにもう一つのルールの発火を導くといったような性質の結合で、言葉を変えて言うと、明らかな(おそらく自明な)論理のつながりがあるということです。もし、ルールのセットがすべて強い結合で結びついていたとすると、それは将来的に柔軟性に欠いたものとなり、さらに重要なこととして、おそらくルールエンジンとしては行き過ぎ(その論理は明白な論理のつながりができており、(通常の言語で)ハードコーディングできるので)となるでしょう。これは、強い結合か弱い結合かが本質的によい悪いと言っているのではなく、ルールエンジンを考えるときに心に留めておきたい点であり、また、ルールセットをどのように捉えるかというところにあります。 「緩く」結合したルールのセットは、あるルールを変更したり、削除したり、追加したりする際に、そのルールとは関係のない他のルールを変更する必要のないようなシステムを形成すべきです。