在商城系统中使用设计模式----策略模式之在spring中使用策略模式

简介: 在商城系统中使用设计模式----策略模式之在spring中使用策略模式1.前言:这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式。2.问题:在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 context 对象。

在商城系统中使用设计模式----策略模式之在spring中使用策略模式
1.前言:

这是策略模式在spring中的使用,对策略模式不了解对同学可以移步在商城中简单对使用策略模式。

2.问题:

在策略模式中,我们创建表示各种策略的对象和一个行为,随着策略对象改变而改变的 context 对象。策略对象改变 context 对象的执行算法。

在spring 中,策略对象在正常情况下是,在启动Spring容器对时候,已经将策略对象加载创建完成成为bean。

我们如何在Spring中正确对使用策略模式,这样又会发生什么问题呢?

3.使用场景: 

场景:商城活动中有几种,满减,打折,送积分.我们要获取商品对最终价格。

4.实现

步骤一.创建接口类

复制代码
public interface GoodsActivity {

/**
 * 获取应该支付的金额
 * @param amount 商品的单价
 * @return
 */
BigDecimal getPayPrice(BigDecimal amount);

}
复制代码
步骤二.实现接口,并添加@Component注解

复制代码
@Component
public class DiscountActivity implements GoodsActivity {

//折扣
private double discount ;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {

    //假装从数据库的配置表取折扣
    discount = 8.0;

    return new BigDecimal(discount).multiply(amount).divide(new BigDecimal(10));
}

}
复制代码
复制代码
@Component
public class FullReduceActivity implements GoodsActivity {

//满多少
private BigDecimal fullAmount;

//减多少
private BigDecimal reductionAmount ;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {

    //假装从数据库的配置表取配置数据
    fullAmount = new BigDecimal(300);

    reductionAmount  = new BigDecimal(100);

    return amount.compareTo(fullAmount)>=0?amount.subtract(reductionAmount):amount;
}

}
复制代码
复制代码
@Component
public class IntegralActivity implements GoodsActivity {

//抵扣的积分  10积分=1元
private int integral = 100;

@Override
public BigDecimal getPayPrice(BigDecimal amount) {
    return amount.subtract(new BigDecimal(integral/10));
}

}
复制代码
步骤三.创建context

复制代码
public class GoodsActivityContext {

private GoodsActivity goodsActivity;

public GoodsActivityContext(GoodsActivity goodsActivity){
    this.goodsActivity=goodsActivity;
}

/**
 * 获取商品价格
 * @param amount
 * @return
 */
public BigDecimal getPrice(BigDecimal amount){
    return goodsActivity.getPayPrice(amount);
}

}
复制代码
步骤四.在控制层中调用策略模式

复制代码
@RestController
public class ActivityController{

@Autowired
private DiscountActivity discountActivity;

@Autowired
private FullReduceActivity fullReduceActivity;

@Autowired
private IntegralActivity integralActivity;
/**
 * 获取最终售价
 *  (这样的控制层写法很不友好,需要写大量的代码去实现)
 *      为了解决这个问题,将引用工厂模式...
 *
 *      工厂是创建型模式,它的作用就是创建对象;
 *      策略是行为型模式,它的作用是让一个对象在许多行为中选择一种行为;
 *
 *  解决不同的问题
 * 工厂模式是创建型的设计模式,它接受指令,创建出符合要求的实例;它主要解决的是资源的统一分发,将对象的创建完全独立出来,让对象的创建和具体的使用客户无关。主要应用在多数据库选择,类库文件加载等。
 * 策略模式是为了解决的是策略的切换与扩展,更简洁的说是定义策略族,分别封装起来,让他们之间可以相互替换,策略模式让策略的变化独立于使用策略的客户。
 *
 * 工厂相当于黑盒子,策略相当于白盒子;
 *
 *
 * @param activityType
 * @param amount
 * @return
 */
@RequestMapping("getLastPrice")
public ResponseResult getLastPrice(String activityType,BigDecimal amount){

    ResponseResult responseResult = ResponseResult.getInstance();

    GoodsActivityContext goodsActivityContext;

    //根据活动类型获取最终售价
    switch (activityType){
        case "discount":
            goodsActivityContext = new GoodsActivityContext(discountActivity);
            break;
        case "fullReduce":
            goodsActivityContext = new GoodsActivityContext(fullReduceActivity);
            break;
        case "integral":
            goodsActivityContext = new GoodsActivityContext(integralActivity);
            break;
        default:
            responseResult.setCode(1);
            responseResult.setMsg("数据类型错误");
            responseResult.setData(null);
            return responseResult;
    }

    responseResult.setCode(0);
    responseResult.setMsg("操作成功");
    responseResult.setData(goodsActivityContext.getPrice(amount));

    return responseResult;
}

}
复制代码

总结:按照注释说明,很明显我们需要优化这个策略模式。

步骤三:(2) 引入工厂模式,对策略对象进行管理

复制代码
@Component
public class GoodsActivityStrategyFactory {

@Autowired
private Map<String,GoodsActivity> goodsActivityMap;

/**
 * 根据活动类型 获取所对应的策略
 * @param activityType
 */
public GoodsActivityContext getGoodsActivityStrategy(String activityType){

    GoodsActivityContext goodsActivityContext;

    switch (activityType){
        case "discount":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("discountActivity"));
            break;
        case "fullReduce":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("fullReduceActivity"));
            break;
        case "integral":
            goodsActivityContext = new GoodsActivityContext(goodsActivityMap.get("integralActivity"));
            break;
        default:
            goodsActivityContext = null;
    }

    return goodsActivityContext;
}

}
复制代码
步骤四.在控制层中调用策略模式

复制代码
@RestController
public class ActivityController{

@Autowired
private GoodsActivityStrategyFactory goodsActivityStrategyFactory;
@RequestMapping("getLastPrice_V2")
public ResponseResult getLastPrice_V2(String activityType,BigDecimal amount){
    ResponseResult responseResult = ResponseResult.getInstance();
    //从工厂中获取  活动策略
    GoodsActivityContext goodsActivityContext = goodsActivityStrategyFactory.getGoodsActivityStrategy(activityType);

    if (goodsActivityContext==null){
        responseResult.setCode(1);
        responseResult.setData(null);
        responseResult.setMsg("数据类型错误");
        return responseResult;
    }

    responseResult.setCode(0);
    responseResult.setMsg("操作成功");
    responseResult.setData(goodsActivityContext.getPrice(amount));

    return responseResult;

}

}
复制代码

源码:

在springboot中使用策略模式

原文地址https://www.cnblogs.com/boychen/p/10721078.html

相关文章
|
19天前
|
设计模式 人工智能 算法
基于多设计模式的状态扭转设计:策略模式与责任链模式的实战应用
接下来,我会结合实战案例,聊聊如何用「策略模式 + 责任链模式」构建灵活可扩展的状态引擎,让抽奖系统的状态管理从「混乱战场」变成「有序流水线」。
|
6月前
|
存储 Java 数据库
Spring Boot 注册登录系统:问题总结与优化实践
在Spring Boot开发中,注册登录模块常面临数据库设计、密码加密、权限配置及用户体验等问题。本文以便利店销售系统为例,详细解析四大类问题:数据库字段约束(如默认值缺失)、密码加密(明文存储风险)、Spring Security配置(路径权限不当)以及表单交互(数据丢失与提示不足)。通过优化数据库结构、引入BCrypt加密、完善安全配置和改进用户交互,提供了一套全面的解决方案,助力开发者构建更 robust 的系统。
177 0
|
4月前
|
设计模式 算法 架构师
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
京东二面:说下spring中常用的设计模式? (一个 深入骨髓的答案, 面试官跪下了)
|
3月前
|
存储 人工智能 自然语言处理
用Spring AI搭建本地RAG系统:让AI成为你的私人文档助手
想让AI帮你读懂PDF文档吗?本文教你用Spring AI和Ollama搭建一个本地RAG系统,让AI成为你的私人文档助手。无需GPU,无需云端API,只需几行代码,你的文档就能开口说话了!
|
5月前
|
设计模式 算法 Java
设计模式觉醒系列(04)策略模式|简单工厂模式的升级版
本文介绍了简单工厂模式与策略模式的概念及其融合实践。简单工厂模式用于对象创建,通过隐藏实现细节简化代码;策略模式关注行为封装与切换,支持动态替换算法,增强灵活性。两者结合形成“策略工厂”,既简化对象创建又保持低耦合。文章通过支付案例演示了模式的应用,并强调实际开发中应根据需求选择合适的设计模式,避免生搬硬套。最后推荐了JVM调优、并发编程等技术专题,助力开发者提升技能。
|
6月前
|
存储 人工智能 Java
Spring AI与DeepSeek实战四:系统API调用
在AI应用开发中,工具调用是增强大模型能力的核心技术,通过让模型与外部API或工具交互,可实现实时信息检索(如天气查询、新闻获取)、系统操作(如创建任务、发送邮件)等功能;本文结合Spring AI与大模型,演示如何通过Tool Calling实现系统API调用,同时处理多轮对话中的会话记忆。
1103 57
|
消息中间件 存储 Java
📨 Spring Boot 3 整合 MQ 构建聊天消息存储系统
本文详细介绍了如何使用Spring Boot 3结合RabbitMQ构建高效可靠的聊天消息存储系统。通过引入消息队列,实现了聊天功能与消息存储的解耦,解决了高并发场景下直接写入数据库带来的性能瓶颈问题。文章首先分析了不同MQ产品的特点及适用场景,最终选择RabbitMQ作为解决方案,因其成熟稳定、灵活路由和易于集成等优势。接着,通过Docker快速部署RabbitMQ,并完成Spring Boot项目的配置与代码实现,包括生产者发送消息、消费者接收并处理消息等功能。最后,通过异步存储机制,既保证了消息的即时性,又实现了可靠持久化。
415 0
📨 Spring Boot 3 整合 MQ 构建聊天消息存储系统
|
4月前
|
Java 调度 流计算
基于Java 17 + Spring Boot 3.2 + Flink 1.18的智慧实验室管理系统核心代码
这是一套基于Java 17、Spring Boot 3.2和Flink 1.18开发的智慧实验室管理系统核心代码。系统涵盖多协议设备接入(支持OPC UA、MQTT等12种工业协议)、实时异常检测(Flink流处理引擎实现设备状态监控)、强化学习调度(Q-Learning算法优化资源分配)、三维可视化(JavaFX与WebGL渲染实验室空间)、微服务架构(Spring Cloud构建分布式体系)及数据湖建设(Spark构建实验室数据仓库)。实际应用中,该系统显著提升了设备调度效率(响应时间从46分钟降至9秒)、设备利用率(从41%提升至89%),并大幅减少实验准备时间和维护成本。
265 0
|
5月前
|
设计模式 算法 搜索推荐
【设计模式】【行为型模式】策略模式(Strategy)
一、入门 什么是策略模式? 策略模式是一种行为设计模式,允许在运行时选择算法或行为。它将算法封装在独立的类中,使得它们可以互换,而不影响客户端代码。 为什么需要策略模式? 策略模式的主要目的是解决算法
112 14
|
7月前
|
人工智能 自然语言处理 Java
对话即服务:Spring Boot整合MCP让你的CRUD系统秒变AI助手
本文介绍了如何通过Model Context Protocol (MCP) 协议将传统Spring Boot服务改造为支持AI交互的智能系统。MCP作为“万能适配器”,让AI以统一方式与多种服务和数据源交互,降低开发复杂度。文章以图书管理服务为例,详细说明了引入依赖、配置MCP服务器、改造服务方法(注解方式或函数Bean方式)及接口测试的全流程。最终实现用户通过自然语言查询数据库的功能,展示了MCP在简化AI集成、提升系统易用性方面的价值。未来,“对话即服务”有望成为主流开发范式。
5272 7