美文网首页
实际项目应用责任链模式

实际项目应用责任链模式

作者: 传达室马大爷 | 来源:发表于2020-03-29 14:19 被阅读0次

需求描述

有一个车系推荐的需求,按照不同的推荐规则返回最近匹配的前N条车系列表,每个推荐规则之间有上下级关系,推荐规则如下

  • 用户画像偏好车系
  • 竞品车系
  • 最近半年报名量排序
  • 当前活动其他车系
  • 随机返回车系
  • 置顶车系
  • 用户画像已购车系
  • 用户手机号最近一次报名车系
  • 品牌匹配车系
  • 用户画像偏好车系竞品车系
  • 专题车系默认车系单表
  • 专题城市车系历史报名量排序
不同的推荐逻辑需要不同的推荐策略组合

开屏弹窗推荐车系列表采用如下三种推荐策略组合,返回前三个匹配车系

  1. 用户画像偏好车系
  2. 用户画像偏好车系竞品车系
  3. 专题车系默认车系单表

单询价页推荐车系采用如下四种推荐策略组合,返回第一个匹配车系

  1. 品牌匹配车系
  2. 用户画像偏好车系
  3. 竞品车系
  4. 随机返回车系

不同推荐策略的组合方式不一样,顺序也不一致

创建AbstractBaseSeriesRecommendService推荐抽象类

import java.util.List;

/**
 * @author mashaohua
 */
public abstract class AbstractBaseSeriesRecommendService {

    // 推送方法
    protected abstract List<TuanActivities> getRecommendSeriesList(SeriesRecommendIn in);

    // 推送策略类型
    protected abstract SeriesRecommendTypeEnum getSeriesRecommendTypeEnum();

}

实现SeriesRecommendTypeEnum枚举定义类型的具体推送方法

import java.util.ArrayList;
import java.util.List;

import com.shawntime.designpattern.chain.AbstractBaseSeriesRecommendService;
import com.shawntime.designpattern.chain.SeriesRecommendIn;
import com.shawntime.designpattern.chain.SeriesRecommendTypeEnum;
import com.shawntime.designpattern.chain.TuanActivities;
import org.springframework.stereotype.Service;

/**
 * @author mashaohua
 * 竞品车系规则处理
 */
@Service
public class CompetingSeriesRecommendService extends AbstractBaseSeriesRecommendService {

    @Override
    protected List<TuanActivities> getRecommendSeriesList(SeriesRecommendIn in) {
        if (in.getSeriesId() <= 0) {
            return new ArrayList<>();
        }
        List<TuanActivities> seriesList = new ArrayList<>();
        // 执行竞品车系推荐规则
        return seriesList;
    }

    @Override
    protected SeriesRecommendTypeEnum getSeriesRecommendTypeEnum() {
        return SeriesRecommendTypeEnum.COMPETING_SERIES;
    }
}
import java.util.ArrayList;
import java.util.List;

import com.shawntime.designpattern.chain.AbstractBaseSeriesRecommendService;
import com.shawntime.designpattern.chain.SeriesRecommendIn;
import com.shawntime.designpattern.chain.SeriesRecommendTypeEnum;
import com.shawntime.designpattern.chain.TuanActivities;
import org.springframework.stereotype.Service;

/**
 * @author mashaohua
 * 置顶车系规则处理
 */
@Service
public class TopSeriesRecommendService extends AbstractBaseSeriesRecommendService {

    @Override
    protected List<TuanActivities> getRecommendSeriesList(SeriesRecommendIn in) {
        if (in.getSeriesId() <= 0) {
            return new ArrayList<>();
        }
        List<TuanActivities> seriesList = new ArrayList<>();
        // 置顶车系
        return seriesList;
    }

    @Override
    protected SeriesRecommendTypeEnum getSeriesRecommendTypeEnum() {
        return SeriesRecommendTypeEnum.USER_PORTRAIT;
    }
}
  • 创建责任链对象SeriesRecommendChain
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;

import org.apache.commons.collections4.CollectionUtils;

/**
 * @author mashaohua
 */
public class SeriesRecommendChain {

    private List<AbstractBaseSeriesRecommendService> filterSeriesRecommendServiceList;

    public void addSeriesRecommendService(List<AbstractBaseSeriesRecommendService> seriesRecommendServiceList,
                                          List<SeriesRecommendTypeEnum> seriesRecommendTypeEnums) {
        for (SeriesRecommendTypeEnum seriesRecommendTypeEnum : seriesRecommendTypeEnums) {
            addSeriesRecommendService(seriesRecommendServiceList, seriesRecommendTypeEnum);
        }
    }

    public void addSeriesRecommendService(List<AbstractBaseSeriesRecommendService> seriesRecommendServiceList,
                                          SeriesRecommendTypeEnum seriesRecommendTypeEnum) {
        if (filterSeriesRecommendServiceList == null) {
            filterSeriesRecommendServiceList = new ArrayList<>();
        }
        if (CollectionUtils.isEmpty(seriesRecommendServiceList)) {
            return;
        }
        Optional<AbstractBaseSeriesRecommendService> optional = seriesRecommendServiceList.stream()
                .filter(service -> service.getSeriesRecommendTypeEnum() == seriesRecommendTypeEnum)
                .findFirst();
        if (optional.isPresent()) {
            filterSeriesRecommendServiceList.add(optional.get());
        }
    }

    public List<SeriesRecommendOut> getRecommendSeriesList(SeriesRecommendIn in) {
        if (CollectionUtils.isEmpty(filterSeriesRecommendServiceList)) {
            return null;
        }
        List<SeriesRecommendOut> seriesRecommendOuts = new ArrayList<>();
        for (AbstractBaseSeriesRecommendService seriesRecommendService : filterSeriesRecommendServiceList) {
            List<TuanActivities> singleTuanActivitiesList =
                    seriesRecommendService.getRecommendSeriesList(in);
            if (singleTuanActivitiesList == null) {
                singleTuanActivitiesList = new ArrayList<>();
            }
            int num = Math.min(singleTuanActivitiesList.size(), in.getTopNum());
            in.setTopNum(Math.max(in.getTopNum() - singleTuanActivitiesList.size(), 0));
            List<TuanActivities> tuanActivitiesList = singleTuanActivitiesList.subList(0, num);
            tuanActivitiesList.forEach(tuanActivities -> {
                SeriesRecommendOut out = new SeriesRecommendOut();
                out.setTuanActivities(tuanActivities);
                out.setSeriesRecommendTypeEnum(seriesRecommendService.getSeriesRecommendTypeEnum());
                seriesRecommendOuts.add(out);
            });
            Set<Integer> filterSeriesIdList = getFilterSeriesIdList(seriesRecommendOuts);
            in.setFilterSeriesIdList(filterSeriesIdList);
            if (in.getTopNum() <= 0) {
                break;
            }
        }
        return seriesRecommendOuts;
    }

    private Set<Integer> getFilterSeriesIdList(List<SeriesRecommendOut> seriesRecommendOuts) {
        if (seriesRecommendOuts == null) {
            return new HashSet<>();
        }
        return seriesRecommendOuts.stream()
                .map(out -> out.getTuanActivities().getSeriesId())
                .collect(Collectors.toSet());
    }
}
  • 具体调用的service拼装责任链
import org.springframework.stereotype.Service;

@Service
public class RecommendSeriesService implements IRecommendSeriesService {

    @Resource
    private List<AbstractBaseSeriesRecommendService> seriesRecommendServiceList;

    @Override
    public List<SeriesRecommendOut> getPopWindowRecommendSeriesList(SeriesRecommendIn in) {
        List<SeriesRecommendTypeEnum> seriesRecommendTypeEnums = new ArrayList<>();
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.USER_PORTRAIT);
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.COMPETING_SERIES);
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.LEADS_COUNT);
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.CURR_ACTIVITY);
        SeriesRecommendChain chain = new SeriesRecommendChain();
        chain.addSeriesRecommendService(seriesRecommendServiceList, seriesRecommendTypeEnums);
        return chain.getRecommendSeriesList(in);
    }

    @Override
    public List<SeriesRecommendOut> getSubjectPageSeriesRecommendSeriesList(SeriesRecommendIn in) {
        List<SeriesRecommendTypeEnum> seriesRecommendTypeEnums = new ArrayList<>();
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.TOP_SERIES);
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.COMPETING_SERIES);
        seriesRecommendTypeEnums.add(SeriesRecommendTypeEnum.USER_PORTRAIT_COMPETING_SERIES);
        SeriesRecommendChain chain = new SeriesRecommendChain();
        chain.addSeriesRecommendService(seriesRecommendServiceList, seriesRecommendTypeEnums);
        return chain.getRecommendSeriesList(in);
    }
}

源码地址:https://github.com/shawntime/shawn-design-pattern

相关文章

网友评论

      本文标题:实际项目应用责任链模式

      本文链接:https://www.haomeiwen.com/subject/ifvnoctx.html