总结
至此,文章终于到了尾声。总结一下,我们谈论了简历制作过程中需要注意的以下三个部分,并分别给出了一些建议:
- 技术能力:先写岗位所需能力,再写加分能力,不要写无关能力;
- 项目经历:只写明星项目,描述遵循 STAR 法则;
- 简历印象:简历遵循三大原则:清晰,简短,必要,要有的放矢,不要海投;
以及最后为大家准备的福利时间:简历模板+Java面试题+热门技术系列教程视频
public interface Rule extends Comparable {
/**
-
此方法封装了规则的条件。
-
@return 如果根据提供的事实可以应用规则,则为true,否则为false
*/
boolean evaluate(Facts facts);
/**
-
此方法封装了规则的操作。
-
@throws 如果在执行操作期间发生错误,则抛出异常
*/
void execute(Facts facts) throws Exception;
//Getters and setters for rule name, description and priority omitted.
}
复制代码
evaluate()
方法封装了必须为true
才能触发规则的条件。execute()
方法封装了在满足规则条件时应该执行的操作。条件和操作由Condition
和Action
接口表示。
规则可以用两种不同的方式定义:
-
通过在
POJO
上添加注解来声明 -
通过
RuleBuilder
API编程
这些是定义规则的最常用方法,但是如果需要,您也可以实现Rule
接口或扩展BasicRule
类。
使用注解定义规则
Easy Rules提供了@Rule
注解,可以将POJO转换为规则。
@Rule(name = “my rule”, description = “my rule description”, priority = 1)
public class MyRule {
@Condition
public boolean when(@Fact(“fact”) fact) {
// 规则条件
return true;
}
@Action(order = 1)
public void then(Facts facts) throws Exception {
// 规则为true时的操作1
}
@Action(order = 2)
public void finally() throws Exception {
// 规则为true时的操作2
}
}
复制代码
@Condition
注解用来标记评估规则条件的方法,这个方法必须是public
,可以有一个或多个带@Fact
注解的参数,并返回一个boolean
类型。只有一个方法可以用@Condition
注解标记。
@Action
注解用来标记执行操作的方法,规则可以有多个操作。可以使用order
属性以指定的顺序执行操作。
使用RuleBuilder
定义规则
RuleBuilder
允许你用流式API定义规则。
Rule rule = new RuleBuilder()
.name(“myRule”)
.description(“myRuleDescription”)
.priority(3)
.when(condition)
.then(action1)
.then(action2)
.build();
复制代码
在本例中,condition
是Condition
接口的实例,action1
和action2
是Action
接口的实例。
组合规则
Easy Rules允许从原始规则创建复杂的规则。一个CompositeRule
由一组规则组成。组合规则是一个抽象概念,因为组合规则可以以不同的方式触发。Easy Rules提供了3种CompositeRule
的实现。
-
UnitRuleGroup
:单元规则组是作为一个单元使用的组合规则,要么应用所有规则,要么不应用任何规则。 -
ActivationRuleGroup
:激活规则组触发第一个适用规则并忽略组中的其他规则。规则首先按照其在组中的自然顺序(默认情况下优先级)进行排序。 -
ConditionalRuleGroup
:条件规则组将具有最高优先级的规则作为条件,如果具有最高优先级的规则的计算结果为true,那么将触发其余的规则。
组合规则可以从原始规则创建并像常规规则一样注册。
// 从两个原始规则创建组合规则
UnitRuleGroup myUnitRuleGroup =
new UnitRuleGroup(“myUnitRuleGroup”, “unit of myRule1 and myRule2”);
myUnitRuleGroup.addRule(myRule1);
myUnitRuleGroup.addRule(myRule2);
// 像常规规则一样注册组合规则
Rules rules = new Rules();
rules.register(myUnitRuleGroup);
RulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.fire(rules, someFacts);
复制代码
规则优先级
Easy Rules中的每个规则都有一个优先级。这表示触发注册规则的默认顺序。默认情况下,值越低优先级越高。要覆盖此行为,您应该重写compareTo()
方法以提供自定义优先级策略。
-
如果是继承
BasicRule
,可以在构造方法中指定优先级,或者重写getPriority()
方法。 -
如果是使用POJO定义规则,可以通过
@Rule
注解的priority
属性指定优先级,或者使用@Priority
注解标记一个方法。这个方法必须是public
,无参却返回类型为Integer
。 -
如果使用
RuleBuilder
定义规则,可以使用RuleBuilder#priority()
方法指定优先级。
Rules API
Easy rules中的一组规则由rules API表示。它的使用方法如下:
Rules rules = new Rules();
rules.register(myRule1);
rules.register(myRule2);
复制代码
Rules
表示已注册规则的命名空间,因此,在同一命名空间下,每一个已经注册的规则必须有唯一的名称。
Rules
是通过Rule#compareTo()
方法进行比较的,因此,Rule
的实现应该正确的实现compareTo()
方法来确保单一空间下拥有唯一的规则名称。
定义事实
Easy Rules中的一个事实是由Fact
表示的:
public class Fact {
private final String name;
private final T value;
}
复制代码
一个事实有一个名称和一个值,两者都不能为null
。另一方面,Facts
API 表示一组事实并充当事实的命名空间。这意味着,在一个Facts
实例中,事实必须有唯一的名称。
下面是一个如何定义事实的例子:
Fact fact = new Fact(“foo”, “bar”);
Facts facts = new Facts();
facts.add(fact);
复制代码
你也可以使用一个更短的版本,用put方法创建命名的事实,如下所示:
Facts facts = new Facts();
facts.put(“foo”, “bar”);
复制代码
可以使用@Fact
注解将事实注入到规则的条件和操作方法中。在以下规则中,rain
事实被注入到itRains
方法的rain
参数中:
@Rule
class WeatherRule {
@Condition
public boolean itRains(@Fact(“rain”) boolean rain) {
return rain;
}
@Action
public void takeAnUmbrella(Facts facts) {
System.out.println(“It rains, take an umbrella!”);
// can add/remove/modify facts
}
}
复制代码
类型为Facts
的参数将被注入所有已知的事实。
注意:
-
如果条件方法中缺少注入的事实,引擎将记录一个警告,并认为条件被计算为
false
。 -
如果动作方法中缺少注入的事实,则不会执行该动作,并且抛出
org.jeasy.rules.core.NoSuchFactException
异常。
定义规则引擎
Easy Rules提供了RulesEngine
接口的两种实现:
-
DefaultRulesEngine
:根据规则的自然顺序(默认为优先级)应用规则。 -
InferenceRulesEngine
:在已知的事实上不断地应用规则,直到没有更多的规则可用。
创建规则引擎
可以使用构造方法创建规则引擎。
RulesEngine rulesEngine = new DefaultRulesEngine();
// or
RulesEngine rulesEngine = new InferenceRulesEngine();
复制代码
可以按如下方式触发已注册的规则。
rulesEngine.fire(rules, facts);
复制代码
规则引擎参数
Easy Rules引擎可以配置以下参数:
| 参数 | 类型 | 默认值 |
| — | — | — |
| rulePriorityThreshold | int | MaxInt |
| skipOnFirstAppliedRule | boolean | false |
| rulePriorityThreshold | int | false |
| skipOnFirstFailedRule | boolean | false |
| skipOnFirstNonTriggeredRule | boolean | false |
-
skipOnFirstAppliedRule
:当一个规则成功应用时,跳过余下的规则。 -
skipOnFirstFailedRule
:当一个规则失败时,跳过余下的规则。 -
skipOnFirstNonTriggeredRule
:当一个规则未触发时,跳过余下的规则。 -
rulePriorityThreshold
:当优先级超过指定的阈值时,跳过余下的规则。
可以使用RulesEngineParameters
API指定这些参数:
RulesEngineParameters parameters = new RulesEngineParameters()
.rulePriorityThreshold(10)
.skipOnFirstAppliedRule(true)
.skipOnFirstFailedRule(true)
.skipOnFirstNonTriggeredRule(true);
RulesEngine rulesEngine = new DefaultRulesEngine(parameters);
复制代码
如果你想从你的引擎中获取参数,你可以使用以下代码段:
RulesEngineParameters parameters = myEngine.getParameters();
复制代码
这允许在创建引擎参数后重新设置引擎参数。
定义规则监听器
可以通过RuleListener
API来监听规则执行事件:
public interface RuleListener {
/**
-
在评估规则之前触发。
-
@param rule 正在被评估的规则
-
@param facts 评估规则之前的已知事实
-
@return 如果规则应该评估,则返回true,否则返回false
*/
default boolean beforeEvaluate(Rule rule, Facts facts) {
return true;
}
/**
-
在评估规则之后触发
-
@param rule 评估之后的规则
-
@param facts 评估规则之后的已知事实
-
@param evaluationResult 评估结果
*/
default void afterEvaluate(Rule rule, Facts facts, boolean evaluationResult) { }
/**
-
运行时异常导致条件评估错误时触发
-
@param rule 评估之后的规则
-
@param facts 评估时的已知事实
-
@param exception 条件评估时发生的异常
*/
default void onEvaluationError(Rule rule, Facts facts, Exception exception) { }
/**
-
在规则操作执行之前触发。
-
@param rule 当前的规则
-
@param facts 执行规则操作时的已知事实
*/
default void beforeExecute(Rule rule, Facts facts) { }
/**
-
在规则操作成功执行之后触发
-
@param rule t当前的规则
-
@param facts 执行规则操作时的已知事实
*/
default void onSuccess(Rule rule, Facts facts) { }
/**
-
在规则操作执行失败时触发
-
@param rule 当前的规则
-
@param facts 执行规则操作时的已知事实
-
@param exception 执行规则操作时发生的异常
*/
default void onFailure(Rule rule, Facts facts, Exception exception) { }
}
复制代码
可以实现这个接口来提供自定义行为,以便在每个规则之前/之后执行。要注册监听器,请使用以下代码段:
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRuleListener(myRuleListener);
复制代码
可以注册任意数量的侦听器,它们将按照注册顺序执行。
注意:当使用组合规则时,监听器是围绕组合规则调用的。
定义规则引擎监听器
可以通过RulesEngineListener
API来监听规则引擎的执行事件:
public interface RulesEngineListener {
/**
-
在执行规则集之前触发
-
@param rules 要触发的规则集
-
@param facts 触发规则前的事实
*/
default void beforeEvaluate(Rules rules, Facts facts) { }
/**
-
在执行规则集之后触发
-
@param rules 要触发的规则集
-
@param facts 触发规则前的事实
*/
default void afterExecute(Rules rules, Facts facts) { }
}
复制代码
RulesEngineListener
允许我们在触发整个规则集之前/之后提供自定义行为。可以使用如下方式注册监听器。
DefaultRulesEngine rulesEngine = new DefaultRulesEngine();
rulesEngine.registerRulesEngineListener(myRulesEngineListener);
复制代码
可以注册任意数量的监听器,它们将按照注册顺序执行。
表达式语言(EL)支持
Easy Rules支持用MVEL
、SpEL
和JEXL
定义规则。
EL提供者注意事项
EL提供者在行为上有一些区别。例如,当一个事实在条件中缺失时,MVEL
抛出一个异常,而SpEL
将忽略它并返回false。因此,在选择Easy Rules使用哪个EL之前,你应该了解这些差异。
通过编程的方式定义规则
条件、动作和规则分别由MVELCondition/SpELCondition/JexlCondition
、MVELAction/SpELAction/JexlAction
和MVELRule/SpELRule/JexlRule
类表示。下面是一个使用MVEL
定义规则的例子:
总结
大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。
麻烦帮忙转发一下这篇文章+关注我
Easy Rules支持用MVEL
、SpEL
和JEXL
定义规则。
EL提供者注意事项
EL提供者在行为上有一些区别。例如,当一个事实在条件中缺失时,MVEL
抛出一个异常,而SpEL
将忽略它并返回false。因此,在选择Easy Rules使用哪个EL之前,你应该了解这些差异。
通过编程的方式定义规则
条件、动作和规则分别由MVELCondition/SpELCondition/JexlCondition
、MVELAction/SpELAction/JexlAction
和MVELRule/SpELRule/JexlRule
类表示。下面是一个使用MVEL
定义规则的例子:
总结
大型分布式系统犹如一个生命,系统中各个服务犹如骨骼,其中的数据犹如血液,而Kafka犹如经络,串联整个系统。这份Kafka源码笔记通过大量的设计图展示、代码分析、示例分享,把Kafka的实现脉络展示在读者面前,帮助读者更好地研读Kafka代码。
麻烦帮忙转发一下这篇文章+关注我
[外链图片转存中…(img-Le0yk8K2-1715404435108)]