样例说明
通过本样例,您可以了解:
- 什么是Reduce策略,目前提供了哪些策略
- 具体的Reduce调用样例
环境准备
您需要:
- 用于运行程序的IDE(集成开发环境),比如IntelliJ IDEA 或其类似工具;
- Java™ Development Kit (JDK),需要JDK 8及以上版本
版本依赖
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-model</artifactId>
<version>1.0.13</version>
</dependency>
<dependency>
<groupId>org.hiforce.lattice</groupId>
<artifactId>lattice-runtime</artifactId>
<version>1.0.13</version>
</dependency>
为什么扩展点执行结果需要Reduce策略
在 Lattice – 关键概念 – 能力 一文中,我们知道能力是可以叠加的。所以,在同一个扩展点上,是可能会产生多个扩展实现。这些扩展实现,会结合业务上下文来决定是否可能会被调用。 比如,Lattice - 业务叠加产品 样例中,“团购产品”的生效条件是,商品销售渠道 等于 “groupBuy”。 但“团购产品”生效后,我们就可以很容易发现,在“商品自定义单价” 这个扩展点上,在业务叠加之后就会产生冲突。“商品单价”究竟是来自业务侧的定义,还是来自“团购产品”的定义?这就需要通过Reduce策略来决定了。
Reduce策略种类
在org.hiforce.lattice.runtime.ability.reduce.Reducers中,我们提供了以下Reduce策略:
- none: 不需要做reduce处理,这个策略常用于返回结果是集合的情况,并且不需要对集合内的空值做处理
- firstOf: 首个命中即返回策略。当扩展点有多份实现,那该策略会从中返回首个命中特定条件的结果
- allMatch: 返回值Boolean类型,判断扩展点所有实现都满足特定条件
- anyMatch: 返回值Boolean类型,判断扩展点所有实现中有任何一个满足特定条件即可
- noneMatch: 返回值Boolean类型,判断扩展点所有实现中都不满足特定条件
- flatList: 扩展点的返回值定义是集合类型,flatList则会把所有所有结果扁平化后输出,而不是嵌套的 List
- 的形式
- flatMap: 扩展点的返回值定义是Map类型,flatMap则会把所有所有结果扁平化后输出,而不是嵌套的 List
Reduce策略DEMO
firstOf 策略
我们在 ReduceSampleAbility 中定义一个扩展点,该扩展点要求返回一个确定的字符串,如下:
public interface ReduceSampleExt extends IBusinessExt {
String EXT_FIRST_NOT_NULL_POLICY = "EXT_FIRST_NOT_NULL_POLICY";
@Extension(code = EXT_FIRST_NOT_NULL_POLICY, reduceType = ReduceType.FIRST)
String firstNotNullReducePolicy();
}
ReduceSampleAbility 会以FirstOf这个策略去调用该扩展点,如下:
@Ability(name = "ReduceSampleAbility")
public class ReduceSampleAbility extends BaseLatticeAbility<BlankReduceSampleExt> {
......
public String sampleFirstNotNullReduce() {
return this.reduceExecute(EXT_FIRST_NOT_NULL_POLICY,
BlankReduceSampleExt::firstNotNullReducePolicy, Reducers.firstOf(Objects::nonNull));
}
......
}
我们让业务和产品分别实现该扩展点,产品的扩展点实现返回空值,而业务则返回一串字符,如下:
@Realization(codes = SampleBusiness.CODE)
public class SampleBusinessExt extends BlankReduceSampleExt {
@Override
public String firstNotNullReducePolicy() {
return "SampleBusiness Hello World!";
}
}
@Realization(codes = SampleProduct.CODE)
public class SampleProductExt extends BlankReduceSampleExt {
@Override
public String firstNotNullReducePolicy() {
return null;
}
}
现在,让我们启动Lattice,模拟一次业务调用过程,启动类是 org.hiforce.lattice.sample.reduce.FirstOfReducer,定义如下:
public class FirstOfReducer {
public static void main(String[] args) {
Lattice.getInstance().setSimpleMode(true);
Lattice.getInstance().start();
SampleScenarioResult result = ReduceSample.startReduceSample(request -> {
ReduceSampleAbility ability = new ReduceSampleAbility(request.getBizObject());
request.getResult().setFirstNotNullResult(ability.sampleFirstNotNullReduce());
return request.getResult();
});
System.out.println("FirstNotNull result => " + result.getFirstNotNullResult());
}
}
执行的结果如下,我们可以看出扩展点执行策略是找到了第一个非空返回值:
FirstNotNull result => SampleBusiness Hello World!
none 策略
我们继续定义一个扩展点,让这个扩展点返回一个List,如下:
public interface ReduceSampleExt extends IBusinessExt {
......
String EXT_CUSTOM_LIST_RESULT = "EXT_CUSTOM_LIST_RESULT";
@Extension(code = EXT_CUSTOM_LIST_RESULT)
List<String> getCustomListResult();
}
我们继续让产品针对这个扩展点,返回空值,而业务则返回一个字符串List,如下:
@Realization(codes = SampleProduct.CODE)
public class SampleProductExt extends BlankReduceSampleExt {
......
@Override
public List<String> getCustomListResult() {
return null;
}
}
@Realization(codes = SampleBusiness.CODE)
public class SampleBusinessExt extends BlankReduceSampleExt {
......
@Override
public List<String> getCustomListResult() {
return Lists.newArrayList("Jack", "Tom");
}
}
现在,让我们启动Lattice,模拟一次业务调用过程,启动类是 org.hiforce.lattice.sample.reduce.FirstOfReducer,定义如下:
public class NoneReducer {
public static void main(String[] args) {
Lattice.getInstance().setSimpleMode(true);
Lattice.getInstance().start();
SampleScenarioResult result = ReduceSample.startReduceSample(request -> {
ReduceSampleAbility ability = new ReduceSampleAbility(request.getBizObject());
request.getResult().setNoneReduceResult(ability.sampleNoneReduce());
return request.getResult();
});
System.out.println("NoneReduce result => " + result.getNoneReduceResult());
}
}
因为该扩展点的返回值定义是List,同时Reduce策略是None。所以,最终的返回结果是一个 ‘List<List
NoneReduce result => [null, [Jack, Tom]]
None() 策略一般用在需要对扩展点返回的多个值做综合判断,比如假设有一个 “订单超时时间” 这个扩展点,我们需要根据所有的结果,返回超时时间最短的值,这时我们就需要用到 None Reduce策略了。
flatList 策略
我们在 none() 策略样例基础上,我们再写一个关于这个扩展点的调用,并将执行结果 List结构,扁平化成一层List ,并且过滤掉空值。我们在能力的调用上,代码如下:
@Ability(name = "ReduceSampleAbility")
public class ReduceSampleAbility extends BaseLatticeAbility<BlankReduceSampleExt> {
......
public List<String> flatListReduce() {
return this.reduceExecute(EXT_CUSTOM_LIST_RESULT,
BlankReduceSampleExt::getCustomListResult,
Reducers.flatList(CollectionUtils::isNotEmpty));
}
......
}
我们运行org.hiforce.lattice.sample.reduce.FlatListReducer,可以看到打印结果如下:
FlatListReducer result => [Jack, Tom]
这个策略已经把List 结果扁平化成一层List进行输出,并且过滤掉了空值。
关于 anyMatch、allMatch、flatMap基本类似,这个可以作为小作业留给大家自行探索。当然,您也可以参考样例中的:
- org.hiforce.lattice.sample.reduce.AllMatchReducer
- org.hiforce.lattice.sample.reduce.AnyMatchReducer
- org.hiforce.lattice.sample.reduce.NoneMatchReducer
发表回复