需求描述
有一个车系推荐的需求,按照不同的推荐规则返回最近匹配的前N条车系列表,每个推荐规则之间有上下级关系,推荐规则如下
- 用户画像偏好车系
- 竞品车系
- 最近半年报名量排序
- 当前活动其他车系
- 随机返回车系
- 置顶车系
- 用户画像已购车系
- 用户手机号最近一次报名车系
- 品牌匹配车系
- 用户画像偏好车系竞品车系
- 专题车系默认车系单表
- 专题城市车系历史报名量排序
不同的推荐逻辑需要不同的推荐策略组合
开屏弹窗推荐车系列表采用如下三种推荐策略组合,返回前三个匹配车系
- 用户画像偏好车系
- 用户画像偏好车系竞品车系
- 专题车系默认车系单表
单询价页推荐车系采用如下四种推荐策略组合,返回第一个匹配车系
- 品牌匹配车系
- 用户画像偏好车系
- 竞品车系
- 随机返回车系
不同推荐策略的组合方式不一样,顺序也不一致
创建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);
}
}
网友评论