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

一、实现思路

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

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

二、整体设计结构

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);
}

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

  • 听力产品推荐

  • 活动商品推荐

  • 套餐组合

  • 分档定价

相关推荐
云原生指北2 分钟前
GitHub Copilot SDK 入门:五分钟构建你的第一个 AI Agent
java
Leinwin4 小时前
OpenClaw 多 Agent 协作框架的并发限制与企业化规避方案痛点直击
java·运维·数据库
薛定谔的悦4 小时前
MQTT通信协议业务层实现的完整开发流程
java·后端·mqtt·struts
enjoy嚣士5 小时前
springboot之Exel工具类
java·spring boot·后端·easyexcel·excel工具类
罗超驿5 小时前
独立实现双向链表_LinkedList
java·数据结构·链表·linkedlist
盐水冰6 小时前
【烘焙坊项目】后端搭建(12) - 订单状态定时处理,来单提醒和顾客催单
java·后端·学习
凸头6 小时前
CompletableFuture 与 Future 对比与实战示例
java·开发语言
wuqingshun3141596 小时前
线程安全需要保证几个基本特征
java·开发语言·jvm
努力也学不会java6 小时前
【缓存算法】一篇文章带你彻底搞懂面试高频题LRU/LFU
java·数据结构·人工智能·算法·缓存·面试
攒了一袋星辰7 小时前
高并发强一致性顺序号生成系统 -- SequenceGenerator
java·数据库·mysql