Простой шаблон проектирования для разработки небольшого Rule-Engine - PullRequest
5 голосов
/ 25 ноября 2010

У меня есть требование, которое принимает множество правил, проверенных на соответствие объектам java-значения, и дает результаты. (мы не можем использовать какие-либо приложения механизма правил в нашей компании, много формальностей и много вопросов, на которые нужно ответить). Таким образом, вместо того, чтобы реализовывать правила, как если бы 'в Java-коде, я предложил реализовать небольшой механизм правил, простой и расширяемый. Какому шаблону дизайна следовать?

Ниже я добавил грубую XML-структуру определенных правил.

  <rule-set>    
    <name>Example1</name>
    <description>Example rules defined</description>

    <beans>
        <bean class="com.example.Customer" alias="cust"/>
        <bean class="com.example.Account" alias="acnt"/>
        <bean class="com.example.Transaction" alias="trans"/>
    </beans>

    <rule name="CustomerInfo" description="This rule validates if all the customer values are present">
        <if lhs="cust.getFirstName" rhs="null" operator="!="/>
        <if lhs="cust.getLastName" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getCountry" rhs="null" operator="!=" logicaloperator="||"/>
        <if lhs="cust.getCity" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getPhone" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <if lhs="cust.getEmail" rhs="null" operator="!=" logicaloperator="&amp;&amp;"/>
        <then do="cust.completeFlag" arg1="true"/>
    </rule>

    <rule name="Transaction" description="Transfer the money from one ac to another">
        <if lhs="trans.fromAccount" operator="!=" rhs="null"/>
        <if lhs="trans.toAccount" operator="!=" rhs="null"/>
        <if lhs="trans.fromAccount.balance" operator=">" rhs="trans.getTransaferAmount"/>
        <then do="trans.fromAccount.debit" arg1="trans.getTransaferAmount"/>
        <then do="trans.toAccount.credit" arg1="trans.getTransaferAmount"/>
    </rule>

</rule-set>

Ответы [ 3 ]

4 голосов
/ 25 ноября 2010

Это действительно зависит от сложности правил, которые вы пытаетесь реализовать.Ключевая идея в декларативном программировании состоит в том, что правила рассматриваются как данные.Итак, самый простой способ начать - это посмотреть, все ли ваши правила могут быть представлены в виде данных в таблице.Например, если ваши правила имеют тип, если a = 10, тогда b = 7, тогда вы можете представить то же самое в таблице и написать общий метод, который может обрабатывать все ваши случаи.

С другой стороны, если ваши правила допускают несколько условий (и / или предложений, а также операторов сравнения), дизайн на основе таблиц не поможет.

В этом случае вам нужно указать грамматику для ваших правил, сгенерировать лексер и парсер.Парсер будет анализировать ваши действительные правила в абстрактном синтаксическом дереве.Добравшись до этого этапа, вы можете либо взять это дерево и нацелить его на существующий механизм правил, либо на свой собственный механизм правил, который знает, как выполнить дерево.

0 голосов
/ 25 ноября 2010

Не совсем то, что вы просили (т.е. шаблон), но, возможно, вы найдете следующий подход полезным, если вы хотите бросить свой собственный:

http://mcqueeney.com/blog/creating-a-simple-rules-engine-using-the-java-scripting-api/

0 голосов
/ 25 ноября 2010

Я бы рекомендовал Шаблон фабричного метода . Каждое правило будет иметь Фабрику, которая может создавать эти правила. Затем я бы заключил все эти Фабрики правил в Абстрактную Фабрику .

В качестве альтернативы вы можете создать Rule Engine как Builder (используя Pattern Builder ), который позволяет передавать наборы правил и создавать правила.

Это то, что я бы сделал лучше всего, но, поскольку я не знаю точных требований вашего механизма правил, то, что пришло в голову.

Возможно, Стратегический паттерн может вам помочь?

...