У меня есть файл правил Drools, к которому я отправляю карту, заполненную пользовательскими объектами (NodeElement), map - это глобальная переменная, потому что к ней должны быть доступны все правила, есть еще одна ошибка глобальной переменной, которая заполняется, когда правило выходит из строя. Я использовал eval и смог успешно его выполнить. После некоторых исследований выяснилось, что у eval есть некоторые проблемы с производительностью?
Мои вопросы...
1) проблемы с производительностью незначительны?
2) использует eval хорошую практику?
3) если мне придется переписать эти правила? что это лучший способ сделать это?
import java.util.Map;
import com.infodev.pojo.NodeElement;
import com.main.Errors;
import com.validation.DateValidation;
global java.util.Map map;
global com.main.Errors errors;
rule "Fixed / Floating ccy rule"
when
eval(!((NodeElement)map.get("FixedCurrency")).getValue().equals(((NodeElement)map.get("FloatingCurrency")).getValue()))
then
errors.addError( "Currency", "Fixed currency should be same as Floating currency" );
end
rule "Payment / Settlement date rule"
when
eval(!(DateValidation.paymentDateValidation(((NodeElement)map.get("tradeDate")).getValue(),((NodeElement)map.get("paymentDate")).getValue())))
then
errors.addError(map.get("paymentDate").toString(), "Payment date should be after trade date" );
end
И карта:
Map<String, NodeElement> map = new HashMap<String, NodeElement>();
map.put("FixedCurrency", new NodeElement("FixedCurrency", "USD"));
map.put("FloatingCurrency", new NodeElement("FloatingCurrency", "UD"));
map.put("tradeDate", new NodeElement("tradeDate", "2012-01-22"));
map.put("paymentDate",new NodeElement("paymentDate", "2012-01-2"));
Учитывая, что NodeElement может быть идентифицирован с использованием той же Строки, которую вы используете в качестве ключа вашей Карты, почему бы вам не вставлять NodeElements в сеанс? Поступая таким образом, вы можете переписать свои правила следующим образом:
rule "Fixed / Floating ccy rule"
when
$n1: NodeElement( id == "FixedCurrency")
$n2: NodeElement( id == "FloatingCurrency", value != $n1.value)
then
errors.addError( "Currency", "Fixed currency should be same as Floating currency" );
end
rule "Payment / Settlement date rule"
when
$n1: NodeElement( id == "tradeDate")
$n2: NodeElement( id == "paymentDate", value != $n1.value)
eval(!(DateValidation.paymentDateValidation($n1.value, $n2.value)))
then
errors.addError($n2.value.toString(), "Payment date should be after trade date" );
end
Я не могу сказать вам, если путем повторного написания ваших правил, как это увеличит вашу производительность или нет. Это будет зависеть и от других вещей. Я думаю, что одна вещь, которую вы получаете от этого нового подхода, - читаемость.
Надеюсь, поможет,
У вас нет правил, у вас есть инструкции (замаскированные под правила), касающиеся значений в объекте Map и другом статическом объекте. (Почему бы вам не запустить эти проверки после добавления на карту?)
Нет никакого eval
я могу видеть в ваших правилах.
Если вам нужен eval
, вам нужно использовать eval
, если вы можете избежать этого, избегайте его.
map.put(...)
. - Как они написаны сейчас, вы должны использовать eval
. Если они будут более сложными, они будут просто более сложными, если заявления под видом правил. И если все они похожи на это, просто получая доступ к нескольким статическим объектам, вы упускаете весь смысл системы производственных правил и можете придерживаться Java.
FixedCurrency
,TradeDate
и т. Д. В качестве имен типов. Это действительно сделает его читабельным ;-)