使用模板模式+策略模式实现产品推荐

一、实现思路

  • 模板方法:固定推荐流程

  • 策略模式:听阈规则 / 价格规则可替换

二、整体设计结构

bash 复制代码
AbstractProductRecommendTemplate
        ↓
  filterByThreshold()   ← 策略①
        ↓
  groupByBrand()
        ↓
  selectByPriceLevel()  ← 策略②
        ↓
  buildResult()

三、第一步:定义"推荐模板"(流程写死)

java 复制代码
public abstract class AbstractProductRecommendTemplate {

    public final List<Product> recommend(List<Product> products, UserProfile user) {

        // 1、 听阈过滤(最关键)
        List<Product> available = filterByThreshold(products, user);
        if (available.isEmpty()) {
            return Collections.emptyList();
        }

        // 2、 按品牌分组
        Map<String, List<Product>> brandMap = groupByBrand(available);

        // 3、 每个品牌选高 / 中 / 低 3种价格的产品,对应不同价格需求的用户群体
        return selectByPriceLevel(brandMap, user);
    }

    protected abstract List<Product> filterByThreshold(
            List<Product> products, UserProfile user);

    protected Map<String, List<Product>> groupByBrand(List<Product> products) {
        return products.stream()
                .collect(Collectors.groupingBy(Product::getBrand));
    }

    protected abstract List<Product> selectByPriceLevel(
            Map<String, List<Product>> brandMap, UserProfile user);
}

四、第二步:听阈匹配策略

1、 策略接口

java 复制代码
public interface ThresholdMatchStrategy {
    boolean match(Product product, UserProfile user);
}

2、实现类

java 复制代码
@Component("DEFAULT_THRESHOLD")
public class DefaultThresholdStrategy implements ThresholdMatchStrategy {

    @Override
    public boolean match(Product p, UserProfile user) {
        return p.getMinHz() <= user.getMinHz()
            && p.getMaxHz() >= user.getMaxHz();
    }
}

五、第三步:价格选择策略

1、 策略接口

java 复制代码
public interface PriceSelectStrategy {

    List<Product> select(List<Product> products);
}

2、 高 / 中 / 低 价格策略

java 复制代码
@Component("HIGH_MID_LOW")
public class HighMidLowPriceStrategy implements PriceSelectStrategy {

    @Override
    public List<Product> select(List<Product> products) {

        if (products.size() <= 3) {
            return products;
        }

        products.sort(Comparator.comparing(Product::getPrice));

        Product low = products.get(0);
        Product mid = products.get(products.size() / 2);
        Product high = products.get(products.size() - 1);

        return List.of(low, mid, high);
    }
}

六、模板的实现类组合使用上面的2个策略

java 复制代码
@Autowired
private ThresholdMatchStrategy thresholdStrategy;

@Autowired
private PriceSelectStrategy priceSelectStrategy;

@Override
protected List<Product> filterByThreshold(List<Product> products, UserProfile user) {
    return products.stream()
            .filter(p -> thresholdStrategy.match(p, user))
            .collect(Collectors.toList());
}

@Override
protected List<Product> selectByPriceLevel(
        Map<String, List<Product>> brandMap, UserProfile user) {

    List<Product> result = new ArrayList<>();

    brandMap.forEach((brand, list) -> {
        result.addAll(priceSelectStrategy.select(list));
    });

    return result;
}

七、Controller / Service 使用方式

java 复制代码
@Autowired
private ProductRecommendService recommendService;

public List<Product> recommend(Long userId) {
    UserProfile user = userService.getProfile(userId);
    List<Product> products = productRepository.findAll();
    return recommendService.recommend(products, user);
}

这套设计特别适用于以下场景:

  • 听力产品推荐

  • 活动商品推荐

  • 套餐组合

  • 分档定价

相关推荐
惊讶的猫6 小时前
探究StringBuilder和StringBuffer的线程安全问题
java·开发语言
jmxwzy7 小时前
Spring全家桶
java·spring·rpc
Halo_tjn7 小时前
基于封装的专项 知识点
java·前端·python·算法
Fleshy数模7 小时前
从数据获取到突破限制:Python爬虫进阶实战全攻略
java·开发语言
像少年啦飞驰点、7 小时前
零基础入门 Spring Boot:从“Hello World”到可上线的 Web 应用全闭环指南
java·spring boot·web开发·编程入门·后端开发
苍煜8 小时前
万字详解Maven打包策略:从基础插件到多模块实战
java·maven
有来技术8 小时前
Spring Boot 4 + Vue3 企业级多租户 SaaS:从共享 Schema 架构到商业化套餐设计
java·vue.js·spring boot·后端
东东5168 小时前
xxx医患档案管理系统
java·spring boot·vue·毕业设计·智慧城市
一个响当当的名号9 小时前
lectrue9 索引并发控制
java·开发语言·数据库
进阶小白猿9 小时前
Java技术八股学习Day30
java·开发语言·学习