日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

rulebook 简单记录

發布時間:2024/1/18 编程问答 34 豆豆
生活随笔 收集整理的這篇文章主要介紹了 rulebook 简单记录 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

總體:

  • 最后發版為2018年
  • 相比EASY RULE,不支持jexl等腳本語言
  • 支持Spring
  • 內部執行都是使用jdk proxy模式,無論是annotation還是builder模式
  • 可以使用CoRRuleBook 實現chain模式,在chain內按order進行執行
  • 一個rule里面可以有多個action(@Then),多個fact(@Given),多個condition(@When),但注意When只有一個會執行
  • 支持將一個java package的所有rule類組成一個Chain-CoRRuleBook
  • 支持audit

核心概念

Much like the Given-When-Then language for defining tests that was popularized by BDD, RuleBook uses a Given-When-Then language for defining rules. The RuleBook Given-When-Then methods have the following meanings.

  • Given some Fact(s)
  • When a condition evaluates to true
  • Then an action is triggered

核心類及示意代碼

rule執行類:GoldenRule

/**
A standard implementation of {@link Rule}.
@param the fact type
@param the Result type
*/
public class GoldenRule<T, U> implements Rule<T, U> {

action 識別代碼

public List<Object> getActions() {if (_rule.getActions().size() < 1) {List<Object> actionList = new ArrayList<>();for (Method actionMethod : getAnnotatedMethods(Then.class, _pojoRule.getClass())) {actionMethod.setAccessible(true);Object then = getThenMethodAsBiConsumer(actionMethod).map(Object.class::cast).orElse(getThenMethodAsConsumer(actionMethod).orElse(factMap -> { }));actionList.add(then);}_rule.getActions().addAll(actionList);}return _rule.getActions(); }

condition 設置和獲取,可以手工指定condition 如:auditableRule.setCondition(condition);
如果沒有設置,使用如下代碼識別

@Override @SuppressWarnings("unchecked") public Predicate<NameValueReferableMap> getCondition() {//Use what was set by then() first, if it's thereif (_rule.getCondition() != null) {return _rule.getCondition();}//If nothing was explicitly set, then convert the method in the class_rule.setCondition(Arrays.stream(_pojoRule.getClass().getMethods()).filter(method -> method.getReturnType() == boolean.class || method.getReturnType() == Boolean.class).filter(method -> Arrays.stream(method.getDeclaredAnnotations()).anyMatch(When.class::isInstance)).findFirst()

注意findFirst,代表只有一個生效

Chain 管理類 CoRRuleBook 使用Reflections 識別package下所有rule類的核心代碼如下:

/*** Gets the POJO Rules to be used by the RuleBook via reflection of the specified package.* @return a List of POJO Rules*/protected List<Class<?>> getPojoRules() {Reflections reflections = new Reflections(_package);List<Class<?>> rules = reflections.getTypesAnnotatedWith(com.deliveredtechnologies.rulebook.annotation.Rule.class).stream().filter(rule -> _package.equals(rule.getPackage().getName())) // Search only within package, not subpackages.filter(rule -> rule.getAnnotatedSuperclass() != null) // Include classes only, exclude interfaces, etc..collect(Collectors.toList());rules.sort(comparingInt(aClass ->getAnnotation(com.deliveredtechnologies.rulebook.annotation.Rule.class, aClass).order()));return rules;}

Fact管理

/*** A Fact is a single piece of data that can be supplied to a {@link Rule}.* Facts are not immutable; they may be changed by rules and used to derive a result state.*/ public class Fact<T> implements NameValueReferable<T> {private String _name;private T _value;/*** A FactMap decorates {@link Map}; it stores facts by their name and provides convenience methods for* accessing {@link Fact} objects.*/ public class FactMap<T> implements NameValueReferableMap<T> {private Map<String, NameValueReferable<T>> _facts;public FactMap(Map<String, NameValueReferable<T>> facts) {_facts = facts;}

實際上有點key重復的感覺,每個fact 本身還有name和value

Then/action 的執行核心代碼 在goldenRule里面

//invoke the actionStream.of(action.getClass().getMethods()).filter(method -> method.getName().equals("accept")).findFirst().ifPresent(method -> {try {method.setAccessible(true);method.invoke(action,ArrayUtils.combine(new Object[]{new TypeConvertibleFactMap<>(usingFacts)},new Object[]{getResult().orElseGet(() -> result)},method.getParameterCount()));if (result.getValue() != null) {_result = result;}} catch (IllegalAccessException | InvocationTargetException err) {LOGGER.error("Error invoking action on " + action.getClass(), err);if (_actionType.equals(ERROR_ON_FAILURE)) {throw err.getCause() == null ? new RuleException(err) :err.getCause() instanceof RuleException ? (RuleException)err.getCause() :new RuleException(err.getCause());}}});facts.putAll(usingFacts); }

多fact示意

fact 通過@Given進行命名

@Rule public class HelloWorld {@Given("hello")private String hello;@Given("world")private String world;

然后復制

facts.setValue("hello", "Hello"); facts.setValue("world", "World");

Spring 使用

@Configuration @ComponentScan("com.example.rulebook.helloworld") public class SpringConfig { @Bean public RuleBook ruleBook() { RuleBook ruleBook = new SpringAwareRuleBookRunner("com.example.rulebook.helloworld"); return ruleBook; } }

擴展

可以擴展rule類,參考RuleAdapter

public RuleAdapter(Object pojoRule, Rule rule) throws InvalidClassException {com.deliveredtechnologies.rulebook.annotation.Rule ruleAnnotation =getAnnotation(com.deliveredtechnologies.rulebook.annotation.Rule.class, pojoRule.getClass());if (ruleAnnotation == null) {throw new InvalidClassException(pojoRule.getClass() + " is not a Rule; missing @Rule annotation");}_actionType = ruleAnnotation.ruleChainAction();_rule = rule == null ? new GoldenRule(Object.class, _actionType) : rule;_pojoRule = pojoRule; }

擴展RuleBook(The RuleBook interface for defining objects that handle the behavior of rules chained together.)

/*** Creates a new RuleBookRunner using the specified package and the supplied RuleBook.* @param ruleBookClass the RuleBook type to use as a delegate for the RuleBookRunner.* @param rulePackage the package to scan for POJO rules.*/public RuleBookRunner(Class<? extends RuleBook> ruleBookClass, String rulePackage) {super(ruleBookClass);_prototypeClass = ruleBookClass;_package = rulePackage;}

當然chain類也可以自己寫。

其它

使用predicate的test 來判斷condition 來
boolean test(T t)
Evaluates this predicate on the given argument.
Parameters:
t - the input argument
Returns:
true if the input argument matches the predicate, otherwise false

使用isAssignableFrom 來判斷輸入的fact 是否滿足rule類里面的定義
isAssignableFrom是用來判斷子類和父類的關系的,或者接口的實現類和接口的關系的,默認所有的類的終極父類都是
Object。如果
A.isAssignableFrom(B)結果是true,證明
B可以轉換成為
A,也就是
A可以由
B轉換而來

總結

以上是生活随笔為你收集整理的rulebook 简单记录的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。