代码下载
设计模式代码全部在gitee上,下载链接: https://gitee.com/xiaozheng2019/desgin_mode.git
日常写代码遇到的囧
1.新建一个类,不知道该放哪个包下
2.方法名称叫A,干得却是A+B+C几件事情,随时隐藏着惊喜
3.想复用一个方法,但是里面嵌套了多余的逻辑,只能自己拆出来,或者重新写一个
4.想调现有方法,但是参数太定制化,要传一些不相关的参数,很不爽,算了,自己写一个
5.每次新增功能,都只能在原来方法中改,但怕影响到旧流程,于是出绝招–加开关
6.想重构一个类,最后几十个类都有改动,有种拔个萝卜带出泥的感觉,为了影响最小,最后改成了四不像
7.超级接口,功能强大到不知道怎么用了
学习设计模式,就能完美解决上面问题吗?
不能,但可以增强写出好代码的意识
文章介绍
本文主要是给大家介绍一下在Spring中策略模式的应用。这里不会扯到策略模式的概念和用例图,实战实战,如果是想看理论的,可以让步,这篇文章对实战很友好哦~~~~~~
背景介绍
有一天,领导对小郑说,有段SQL的过滤逻辑复杂,日常生产运维,需要查某某数据为什么没出现,被什么条件给过滤掉了。小郑同学,你能不能转化成Java代码,帮忙写个工具快速知道数据被什么过滤。
每个业务支持不同的规律规则,两条业务线在走,未来可能新增多种过滤规则,支持可扩展。
提取领导的要求:
- 多条业务线
- 过滤规则可配置
- 过滤规则可扩展
- 本需求响应结果简单,是否过滤,布尔类型即可
思路分析
策略模式+工厂模式,拿到策略执行即可
代码
版本1
如果说,不采用任何设计模式的话,直接用条件判断。
每个过滤逻辑是单独的方法,然后用if-else 调用不同方法的写法,这就很冗余了,代码不展示
版本2 简单演示一下策略模式
步骤1:定义策略接口
package com.dgut.edu.cn.design.mode.filterchain.filter;
import com.dgut.edu.cn.design.mode.filterchain.dto.RuleFilterResVo;
/**
* @description: 规则过滤接口
* @author: hongbin.zheng
* @create: 2023-08-10 18:41
**/
public interface RuleFilter<T> {
/**
* 执行过滤响应结果
* @return
*/
RuleFilterResVo doFilter(T entity) throws Exception;
/**
* 过滤链名字
* @return
*/
String name();
}
步骤2:响应结果封装,当然这里返回boolean类型也是可以
package com.dgut.edu.cn.design.mode.filterchain.dto;
import lombok.Data;
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 18:42
**/
@Data
public class RuleFilterResVo {
/**
* 过滤结果
*/
private boolean isFilter;
/**
* 响应状态码
*/
private Integer msgCode;
/**
* 响应数据
*/
private Object msg;
/**
* 过滤器名称
*/
private String ruleFilterName;
/**
* 响应不过滤信息
* @param ruleFilterName
* @return
*/
public static RuleFilterResVo ok(String ruleFilterName) {
RuleFilterResVo ruleFilterResVo = new RuleFilterResVo();
ruleFilterResVo.setFilter(false);
ruleFilterResVo.setMsgCode(200);
ruleFilterResVo.setRuleFilterName(ruleFilterName);
ruleFilterResVo.setMsg(null);
return ruleFilterResVo;
}
/**
* 响应过滤信息
* @param msg
* @param ruleFilterName
* @return
*/
public static RuleFilterResVo fail(Object msg, String ruleFilterName) {
RuleFilterResVo ruleFilterResVo = new RuleFilterResVo();
ruleFilterResVo.setFilter(true);
ruleFilterResVo.setMsgCode(200);
ruleFilterResVo.setRuleFilterName(ruleFilterName);
ruleFilterResVo.setMsg(msg);
return ruleFilterResVo;
}
}
步骤三: 编写过滤实现类
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 18:49
**/
@Service
public class MerItemNoRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if (priceCompareResult.getMerItemNo() % 10 == 0) {
// 如果 尺码 被 10整除,则过滤
return RuleFilterResVo.fail("若 merItemNo 被 10整除,则过滤,merItemNo = " + priceCompareResult.getMerItemNo(), name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "merItemNoRuleFilter";
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 18:49
**/
@Service
public class MidRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if (priceCompareResult.getMerchandiseNo() % 10 == 0) {
// 如果mid 被 10整除,则过滤
return RuleFilterResVo.fail("若mid 被 10整除,则过滤,mid = " + priceCompareResult.getMerchandiseNo(), name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "midRuleFilter";
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 18:49
**/
@Service
public class MpRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if ((byte) 0 == priceCompareResult.getIsMp()) {
// 非MP ,则过滤
return RuleFilterResVo.fail(" 非MP ,则过滤", name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "mpRuleFilter";
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 18:49
**/
@Service
public class OpponentSiteRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
List<Long> siteList = Lists.newArrayList(1001L, 1002L);
if (!siteList.contains(priceCompareResult.getOpponentPriceId())) {
// 如果 站点非1001,1002 ,则过滤
return RuleFilterResVo.fail("如果 站点非1001,1002 ,则过滤", name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "opponentSiteRuleFilter";
}
}
步骤4:实体类:
@Data
@Builder(builderMethodName = "of",buildMethodName = "get")
public class PriceCompareResult {
private Long id;
private Long opponentPriceId;
private Long merItemNo;
private Long merchandiseNo;
private String goodsName;
private String sizeName;
private Long salesNo;
private Byte isT4000;
private Byte isMp;
}
步骤5:编写测试类
/**
* 测试第一种过滤策略
*/
@Test
public void testBatchExecute() throws Exception {
List<PriceCompareResult> priceCompareResultList = Lists.newArrayList();
PriceCompareResult one = PriceCompareResult.of().merchandiseNo(100L).merItemNo(157L).get();
PriceCompareResult one2 = PriceCompareResult.of().merchandiseNo(107L).merItemNo(150L).get();
PriceCompareResult one3 = PriceCompareResult.of().merchandiseNo(8L).merItemNo(7L).get();
PriceCompareResult one4 = PriceCompareResult.of().merchandiseNo(6L).merItemNo(5L).get();
priceCompareResultList.add(one);
priceCompareResultList.add(one2);
priceCompareResultList.add(one3);
priceCompareResultList.add(one4);
System.out.println(MyFilterChainType.BUSINESS_ONE);
System.out.println(MyFilterChainType.BUSINESS_ONE.name);
List<RuleFilter> ruleFilterList = Lists.newArrayList();
ruleFilterList.add(new MerItemNoRuleFilter());
ruleFilterList.add(new MidRuleFilter());
for (PriceCompareResult priceCompareResult : priceCompareResultList) {
for (RuleFilter ruleFilter : ruleFilterList) {
RuleFilterResVo ruleFilterResVo = ruleFilter.doFilter(priceCompareResult);
System.out.println(ruleFilterResVo);
}
}
}
小总结:上述就是很清晰的策略模式代码。可以指定过滤实现类,添加到List里面然后去执行
版本3 Spring实战
前提介绍小工具,从文件中解析出配置:
public class CfgCenterUtils {
public static String getCfgString(String configKey, String defaultValue) {
// 获取资源文件的 InputStream
String resource = String.format("%s.json", configKey);
InputStream inputStream = CfgCenterUtils.class.getResourceAsStream("/cfg/" + resource);
if (inputStream != null) {
try {
// 使用 InputStreamReader 读取 InputStream
InputStreamReader reader = new InputStreamReader(inputStream, StandardCharsets.UTF_8);
// 使用 BufferedReader 读取内容
BufferedReader bufferedReader = new BufferedReader(reader);
StringBuilder jsonString = new StringBuilder();
String line;
while ((line = bufferedReader.readLine()) != null) {
jsonString.append(line);
}
// 输出解析结果
/*System.out.println("Parsed JSON string: " + jsonString.toString());*/
return jsonString.toString();
} catch (Exception e) {
e.printStackTrace();
}
} else {
//System.out.println("Resource not found.");
return defaultValue;
}
return defaultValue;
}
}
测试用例:
@Test
public void JsonParsingExampleTest() {
String filterChainConfig = CfgCenterUtils.getCfgString("PC_RESULT_FILTER_CHAIN", "");
System.out.println(filterChainConfig);
}
步骤1: 定义业务类型:三条业务线
/**
* @description: 过滤链业务
* @author: hongbin.zheng
* @create: 2023-08-11 10:19
**/
public enum MyFilterChainType {
BUSINESS_ONE("businessOne"),
BUSINESS_TWO("businessTwo"),
BUSINESS_THIRD("businessThird");
String name;
MyFilterChainType(String name) {
this.name = name;
}
public String getName() {
return name;
}
}
步骤2: 定义接口和实现
public interface RuleFilter<T> {
/**
* 执行过滤响应结果
* @return
*/
RuleFilterResVo doFilter(T entity) throws Exception;
/**
* 过滤链名字
* @return
*/
String name();
}
@Service
public class MerItemNoRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if (priceCompareResult.getMerItemNo() % 10 == 0) {
// 如果 尺码 被 10整除,则过滤
return RuleFilterResVo.fail("若 merItemNo 被 10整除,则过滤,merItemNo = " + priceCompareResult.getMerItemNo(), name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "merItemNoRuleFilter";
}
}
@Service
public class MidRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if (priceCompareResult.getMerchandiseNo() % 10 == 0) {
// 如果mid 被 10整除,则过滤
return RuleFilterResVo.fail("若mid 被 10整除,则过滤,mid = " + priceCompareResult.getMerchandiseNo(), name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "midRuleFilter";
}
}
@Service
public class MpRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
if ((byte) 0 == priceCompareResult.getIsMp()) {
// 非MP ,则过滤
return RuleFilterResVo.fail(" 非MP ,则过滤", name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "mpRuleFilter";
}
}
@Service
public class OpponentSiteRuleFilter implements RuleFilter<PriceCompareResult> {
@Override
public RuleFilterResVo doFilter(PriceCompareResult priceCompareResult) throws Exception{
List<Long> siteList = Lists.newArrayList(1001L, 1002L);
if (!siteList.contains(priceCompareResult.getOpponentPriceId())) {
// 如果 站点非1001,1002 ,则过滤
return RuleFilterResVo.fail("如果 站点非1001,1002 ,则过滤", name());
}
return RuleFilterResVo.ok(name());
}
@Override
public String name() {
return "opponentSiteRuleFilter";
}
}
public interface PriceCompareHandle<T> {
void handler(T entity);
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 19:05
**/
@Service
public class FirstTestPriceCompareHandle implements PriceCompareHandle<PriceCompareResult>{
@Override
public void handler(PriceCompareResult entity) {
System.out.println("FirstTestPriceCompareHandle.........execute 保存数据库等操作 start");
System.out.println(entity.toString());
System.out.println("FirstTestPriceCompareHandle.........execute 保存数据库等操作 end");
}
}
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-10 19:05
**/
@Service
public class SecondTestPriceCompareHandle implements PriceCompareHandle<PriceCompareResult>{
@Override
public void handler(PriceCompareResult entity) {
System.out.println("SecondTestPriceCompareHandle.........execute 保存数据库等操作 start");
System.out.println(entity.toString());
System.out.println("SecondTestPriceCompareHandle.........execute 保存数据库等操作 end");
}
}
步骤3: 定义配置
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-11 10:23
**/
@Data
public class FilterChainConfig {
private String name;
private List<String> handlerList;
private List<String> filterList;
}
步骤4: 定义过滤链结果
package com.dgut.edu.cn.design.mode.filterchain;
import com.dgut.edu.cn.design.mode.filterchain.dto.RuleFilterResVo;
import com.dgut.edu.cn.design.mode.filterchain.filter.RuleFilter;
import com.dgut.edu.cn.design.mode.filterchain.handler.PriceCompareHandle;
import com.dgut.edu.cn.design.mode.log.LogMsgKit;
import com.google.common.collect.Lists;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import java.util.*;
/**
* @description: 每个业务具体拿到业务过滤链结果
* @author: hongbin.zheng
* @create: 2023-08-11 10:29
**/
@Slf4j
@Data
public class FilterChain<T> {
private String name;
private List<PriceCompareHandle<T>> priceCompareHandleList;
private List<RuleFilter<T>> ruleFilterList;
public FilterChain() {
}
public FilterChain(String name) {
this.name = name;
this.priceCompareHandleList = Lists.newArrayList();
this.ruleFilterList = Lists.newArrayList();
}
public FilterChain(String name, List<PriceCompareHandle<T>> priceCompareHandleList,
List<RuleFilter<T>> ruleFilterList) {
this.name = name;
this.priceCompareHandleList = priceCompareHandleList;
this.ruleFilterList = ruleFilterList;
}
public T process(T entity) throws Exception {
if (ruleFilterList.size() > 0) {
for (RuleFilter<T> ruleFilter : ruleFilterList) {
RuleFilterResVo ruleFilterResVo = ruleFilter.doFilter(entity);
if (ruleFilterResVo.isFilter()) {
log.info(LogMsgKit.of("FilterChain_process").p("filterName", ruleFilterResVo.getRuleFilterName())
.p("entity", entity).p("triggerRule", ruleFilterResVo.getMsg()).end("没有通过该过滤器"));
return null;
}
}
// 能达到这一步的都是 符合业务的数据,执行业务操作
}
if (priceCompareHandleList.size() > 0) {
for (PriceCompareHandle<T> handle : priceCompareHandleList) {
handle.handler(entity);
}
}
return entity;
}
}
步骤5: 工厂模式构建过滤链:
package com.dgut.edu.cn.design.mode.filterchain;
import com.dgut.edu.cn.design.mode.filterchain.filter.RuleFilter;
import com.dgut.edu.cn.design.mode.filterchain.handler.PriceCompareHandle;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Service;
import javax.annotation.PostConstruct;
import java.util.Map;
/**
* @description: 需要解析配置,然后拿到每个业务的过滤点模式
* @author: hongbin.zheng
* @create: 2023-08-11 10:26
**/
@Service
@Slf4j
public class FilterChainFactory<T> {
@Autowired
private ApplicationContext applicationContext;
private Map<String, RuleFilter> ruleFilterMap;
private Map<String, PriceCompareHandle> priceCompareHandleMap;
@PostConstruct
public void init() throws NoSuchMethodException {
ruleFilterMap = Maps.newHashMap();
priceCompareHandleMap = Maps.newHashMap();
Map<String, RuleFilter> filterBeanMap = applicationContext.getBeansOfType(RuleFilter.class);
for (Map.Entry<String, RuleFilter> entry : filterBeanMap.entrySet()) {
ruleFilterMap.put(entry.getKey(), entry.getValue());
}
Map<String, PriceCompareHandle> handleBeanMap = applicationContext.getBeansOfType(PriceCompareHandle.class);
for (Map.Entry<String, PriceCompareHandle> entry : handleBeanMap.entrySet()) {
priceCompareHandleMap.put(entry.getKey(), entry.getValue());
}
}
public <T> FilterChain<T> createChains(FilterChainConfig config, Class<T> tClass) {
FilterChain<T> filterChain = new FilterChain<T>(config.getName());
if (CollectionUtils.isNotEmpty(config.getFilterList())) {
for (String ruleFilterName : config.getFilterList()) {
RuleFilter<T> ruleFilter = ruleFilterMap.get(ruleFilterName);
if (ruleFilter != null) {
filterChain.getRuleFilterList().add(ruleFilter);
}
}
}
if (CollectionUtils.isNotEmpty(config.getHandlerList())) {
for (String handle : config.getHandlerList()) {
PriceCompareHandle<T> priceCompareHandle = priceCompareHandleMap.get(handle);
if (priceCompareHandle != null) {
filterChain.getPriceCompareHandleList().add(priceCompareHandle);
}
}
}
return filterChain;
}
}
步骤6: 业务类:
package com.dgut.edu.cn.design.mode.filterchain;
import com.alibaba.fastjson.JSONArray;
import com.dgut.edu.cn.design.mode.filterchain.dto.PriceCompareResult;
import com.dgut.edu.cn.design.mode.log.LogMsgKit;
import com.dgut.edu.cn.design.mode.utils.CfgCenterUtils;
import com.google.common.collect.Maps;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.DigestUtils;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-11 11:15
**/
@Slf4j
@Service
public class FilterChainService {
@Autowired
private FilterChainFactory filterChainFactory;
/**
* 生成的过滤链
*/
private Map<String,FilterChain<PriceCompareResult>> filterChains = Maps.newHashMap();
/**
* 老配置的md5
*/
private String oldConfigMd5;
/**
* 批量进行过滤
*
* @param priceCompareResults
* @return
*/
public List<PriceCompareResult> batchExecute(List<PriceCompareResult> priceCompareResults, MyFilterChainType type) {
checkChains();
return priceCompareResults.stream()
.filter(priceCompareResult -> executeWithoutCheckChains(priceCompareResult, type) != null)
.collect(Collectors.toList());
}
private void checkChains() {
try {
String filterChainConfig = CfgCenterUtils.getCfgString("PC_RESULT_FILTER_CHAIN", "");
if (StringUtils.isEmpty(filterChainConfig)) {
log.info(LogMsgKit.of("checkChains").p("filterChainConfig", filterChainConfig).end("配置为空"));
return;
}
String newConfigMd5 = DigestUtils.md5DigestAsHex(filterChainConfig.getBytes());
if (!newConfigMd5.equals(oldConfigMd5)) {
List<FilterChainConfig> configs = JSONArray.parseArray(filterChainConfig, FilterChainConfig.class);
Map<String,FilterChain<PriceCompareResult>> map = Maps.newHashMap();
for (FilterChainConfig config : configs) {
FilterChain<PriceCompareResult> chain = filterChainFactory.createChains(config,
PriceCompareResult.class);
map.put(chain.getName(),chain);
}
oldConfigMd5 = newConfigMd5;
filterChains.clear();
filterChains = map;
}
} catch (Exception e) {
log.error(LogMsgKit.of("PcResultFilterAdmin_checkChains").end("新增或更新过滤链失败"), e);
}
}
public PriceCompareResult executeWithoutCheckChains(PriceCompareResult compareResult, MyFilterChainType type) {
FilterChain<PriceCompareResult> chain = filterChains.get(type.getName());
if (chain == null) {
log.warn(LogMsgKit.of("PcResultFilterAdmin_executeWithoutCheckChains").p("FilterType", type).end("没有该过滤链"));
return null;
}
try {
return chain.process(compareResult);
} catch (Exception e) {
log.error(LogMsgKit.of("PcResultFilterAdmin_executeWithoutCheckChains").p("filterChain", chain).p("result", compareResult)
.end("执行失败"), e);
}
return compareResult;
}
}
步骤7:测试
package com.dgut.edu.cn.design.mode.filterchain;
import com.dgut.edu.cn.design.mode.BaseTest;
import com.dgut.edu.cn.design.mode.filterchain.dto.PriceCompareResult;
import com.google.common.collect.Lists;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.*;
/**
* @description:
* @author: hongbin.zheng
* @create: 2023-08-11 12:05
**/
@SpringBootTest
public class FilterChainServiceTest extends BaseTest {
@Autowired
private FilterChainService filterChainService;
/**
* 测试第一种过滤策略
*/
@Test
public void testBatchExecute() {
List<PriceCompareResult> priceCompareResultList = Lists.newArrayList();
PriceCompareResult one = PriceCompareResult.of().merchandiseNo(100L).merItemNo(157L).get();
PriceCompareResult one2 = PriceCompareResult.of().merchandiseNo(107L).merItemNo(150L).get();
PriceCompareResult one3 = PriceCompareResult.of().merchandiseNo(8L).merItemNo(7L).get();
PriceCompareResult one4 = PriceCompareResult.of().merchandiseNo(6L).merItemNo(5L).get();
priceCompareResultList.add(one);
priceCompareResultList.add(one2);
priceCompareResultList.add(one3);
priceCompareResultList.add(one4);
System.out.println(MyFilterChainType.BUSINESS_ONE);
System.out.println(MyFilterChainType.BUSINESS_ONE.name);
List<PriceCompareResult> priceCompareResults = filterChainService
.batchExecute(priceCompareResultList, MyFilterChainType.BUSINESS_ONE);
print(priceCompareResults);
}
/**
* 测试第二种过滤策略
*/
@Test
public void testBatchExecute2() {
List<PriceCompareResult> priceCompareResultList = Lists.newArrayList();
PriceCompareResult one = PriceCompareResult.of().merchandiseNo(100L).merItemNo(157L).isMp((byte) 1).get();
PriceCompareResult one2 = PriceCompareResult.of().merchandiseNo(107L).isMp((byte) 1).merItemNo(150L).get();
PriceCompareResult one3 = PriceCompareResult.of().merchandiseNo(8L).isMp((byte) 1).merItemNo(7L).get();
PriceCompareResult one4 = PriceCompareResult.of().merchandiseNo(6L).isMp((byte) 0).merItemNo(5L).get();
priceCompareResultList.add(one);
priceCompareResultList.add(one2);
priceCompareResultList.add(one3);
priceCompareResultList.add(one4);
List<PriceCompareResult> priceCompareResults = filterChainService
.batchExecute(priceCompareResultList, MyFilterChainType.BUSINESS_TWO);
print(priceCompareResults);
}
/**
* 测试第3种过滤策略
*/
@Test
public void testBatchExecute3() {
List<PriceCompareResult> priceCompareResultList = Lists.newArrayList();
PriceCompareResult one = PriceCompareResult.of().merchandiseNo(100L).merItemNo(157L).isMp((byte) 1).opponentPriceId(1003L).get();
PriceCompareResult one2 = PriceCompareResult.of().merchandiseNo(107L).isMp((byte) 1).opponentPriceId(1001L).merItemNo(150L).get();
PriceCompareResult one3 = PriceCompareResult.of().merchandiseNo(8L).isMp((byte) 1).opponentPriceId(1001L).merItemNo(7L).get();
PriceCompareResult one4 = PriceCompareResult.of().merchandiseNo(6L).isMp((byte) 0).opponentPriceId(1001L).merItemNo(5L).get();
priceCompareResultList.add(one);
priceCompareResultList.add(one2);
priceCompareResultList.add(one3);
priceCompareResultList.add(one4);
List<PriceCompareResult> priceCompareResults = filterChainService
.batchExecute(priceCompareResultList, MyFilterChainType.BUSINESS_THIRD);
print(priceCompareResults);
}
}