问题:通过策略模式+工厂模式+模板方法模式实现ifelse优化

embedded/2025/2/13 14:58:21/

项目场景:

提示:这里简述项目相关背景:

示例:商城系统有会员系统,不同会员有不同优惠程度,普通会员不优惠;黄金会员打8折;白金会员优惠50元,再打7折;


问题描述

提示:这里描述项目中遇到的问题:

例如:不同会员处理过程中,业务场景复杂,每种会员的业务逻辑很长,不方便维护。

public static double quote(String type) {double score = 1000;double res = 0;if (type.equals("1")) {res = score;} else if (type.equals("2")) {res = score - 50;} else if (type.equals("3")) {res = score * 0.8;} else if (type.equals("4")) {res = (score - 50) * 0.7;}return res;}

原因分析:

提示:这里填写问题的分析:

业务复杂


解决方案:

在这里插入图片描述

提示:这里填写该问题的具体解决方案:

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;public interface PayStrategy {/*** 计算费用** @param price* @date 2025-02-10*/BigDecimal quote(BigDecimal price);
}

具体策略1:非会员,没有优惠

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;public class OrdinaryStrategy implements PayStrategy{@Overridepublic BigDecimal quote(BigDecimal price) {return price;}
}

具体策略2:黄金会员,打八折

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;
import java.util.Objects;public class GoldStrategy implements PayStrategy{@Overridepublic BigDecimal quote(BigDecimal price) {BigDecimal res = price.multiply(new BigDecimal("0.8"));return res;}
}

具体策略3:白银会员,先优惠50,后打七折

package com.geekmice.springbootmybatiscrud.strategy.third;import com.geekmice.springbootmybatiscrud.strategy.first.Strategy;import java.math.BigDecimal;public class PlatinumStrategy implements PayStrategy {@Overridepublic BigDecimal quote(BigDecimal price) {BigDecimal res = price.subtract(new BigDecimal("50")).multiply(new BigDecimal("0.7"));return res;}
}

上下文对象:持有一个Strategy的引用

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;/*** @author Administrator*/
public class PayContext {private PayStrategy payStrategy;public void setStrategy(PayStrategy payStrategy) {this.payStrategy = payStrategy;}public BigDecimal getPrice(BigDecimal price) {if (payStrategy != null) {return payStrategy.quote(price);}return null;}
}

测试使用

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;public class Demo {public static void main(String[] args) {PayContext payContext = new PayContext();OrdinaryStrategy ordinaryStrategy = new OrdinaryStrategy();payContext.setStrategy(ordinaryStrategy);System.out.println("普通会员:"+payContext.getPrice(new BigDecimal("100")));GoldStrategy goldStrategy = new GoldStrategy();payContext.setStrategy(goldStrategy);System.out.println("黄金会员:"+payContext.getPrice(new BigDecimal("100")));PlatinumStrategy platinumStrategy = new PlatinumStrategy();payContext.setStrategy(platinumStrategy);System.out.println("白银会员:"+payContext.getPrice(new BigDecimal("100")));}
}

结果

普通会员:100
黄金会员:80.0
白银会员:35.0

优化1:新增其他策略,不影响现有的策略

思路:新增策略类,实现策略接口

package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;public class SilverStrategy implements PayStrategy{@Overridepublic BigDecimal quote(BigDecimal price) {return price.subtract(new BigDecimal("50"));}
}package com.geekmice.springbootmybatiscrud.strategy.third;import java.math.BigDecimal;public class Demo {public static void main(String[] args) {PayContext payContext = new PayContext();OrdinaryStrategy ordinaryStrategy = new OrdinaryStrategy();payContext.setStrategy(ordinaryStrategy);System.out.println("普通会员:"+payContext.getPrice(new BigDecimal("100")));GoldStrategy goldStrategy = new GoldStrategy();payContext.setStrategy(goldStrategy);System.out.println("黄金会员:"+payContext.getPrice(new BigDecimal("100")));PlatinumStrategy platinumStrategy = new PlatinumStrategy();payContext.setStrategy(platinumStrategy);System.out.println("白银会员:"+payContext.getPrice(new BigDecimal("100")));SilverStrategy silverStrategy = new SilverStrategy();payContext.setStrategy(silverStrategy);System.out.println("白金会员:"+payContext.getPrice(new BigDecimal("100")));}
}

普通会员:100
黄金会员:80.0
白银会员:35.0
白金会员:50

优化2:策略中出现相同逻辑,如何处理

说明:策略2与策略3处理逻辑中都有需要处理的内容,这个内容可能很长,初始化参数,或者校验参数,远程调用获取数据等操作,都是类似的逻辑,可以抽取到抽象类中,子类需要哪个实现哪个方法,重复的直接在父类操作。

在这里插入图片描述

策略工厂

package com.geekmice.springbootmybatiscrud.strategy.fifth;import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
/*** @author mbp* @date 2025-02-11*/
public class StrategyFactory {/*** 设置策略map*/private static Map<String, Strategy> strategyMap = new HashMap<>(16);public static Strategy getStrategyService(String type) {return strategyMap.get(type);}/*** 提前策略装入 strategyMap*/public static void register(String type, Strategy strategy) {if (Objects.isNull(type)) {return;}strategyMap.put(type, strategy);}
}

策略接口

package com.geekmice.springbootmybatiscrud.strategy.fifth;import org.springframework.beans.factory.InitializingBean;import java.math.BigDecimal;
/*** @author mbp* @date 2025-02-11*/
public interface Strategy extends InitializingBean {BigDecimal quote(BigDecimal price);}

模板方式抽象类

package com.geekmice.springbootmybatiscrud.strategy.fifth;/*** @author mbp* @date 2025-02-11*/
public abstract class BaseMember {/*** 需要父类执行关键重复逻辑*/protected void exec(){System.out.println("处理内容");}}

具体策略1

package com.geekmice.springbootmybatiscrud.strategy.fifth;import org.springframework.stereotype.Component;import java.math.BigDecimal;
/*** @author mbp* @date 2025-02-11*/
@Component
public class OrdinaryStrategy extends BaseMember  implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {this.exec();return price;}@Overridepublic void afterPropertiesSet() throws Exception {StrategyFactory.register("1",this);}
}

具体策略2

package com.geekmice.springbootmybatiscrud.strategy.fifth;import org.springframework.stereotype.Component;import java.math.BigDecimal;
/*** @author mbp* @date 2025-02-11*/
@Component
public class GoldStrategy extends BaseMember implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {BigDecimal res = price.multiply(new BigDecimal("0.8"));this.exec();return res;}@Overridepublic void afterPropertiesSet() throws Exception {StrategyFactory.register("2", this);}}

具体策略3

package com.geekmice.springbootmybatiscrud.strategy.fifth;import org.springframework.stereotype.Component;import java.math.BigDecimal;
/*** @author mbp* @date 2025-02-11*/
@Component
public class PlatinumStrategy extends BaseMember implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {BigDecimal res = price.subtract(new BigDecimal("50")).multiply(new BigDecimal("0.7"));return res;}@Overridepublic void afterPropertiesSet() throws Exception {StrategyFactory.register("3", this);}
}

测试类

package com.geekmice.springbootmybatiscrud.controller;import com.geekmice.springbootmybatiscrud.dao.StudentMapper;
import com.geekmice.springbootmybatiscrud.pojo.Student;
import com.geekmice.springbootmybatiscrud.strategy.fifth.Strategy;
import com.geekmice.springbootmybatiscrud.strategy.fifth.StrategyFactory;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;/*** @author Administrator*/
@RestController
@RequestMapping("/student")
public class StudentController {@Resourceprivate StudentMapper studentMapper;@GetMapping(value = "queryAll")public List<Student> queryAll() {Strategy strategyService = StrategyFactory.getStrategyService("1");System.out.println(strategyService.quote(new BigDecimal("1000")));Strategy strategyService2 = StrategyFactory.getStrategyService("2");System.out.println(strategyService2.quote(new BigDecimal("1000")));Strategy strategyService1 = StrategyFactory.getStrategyService("3");System.out.println(strategyService1.quote(new BigDecimal("1000")));return new ArrayList<>();}}

优化3:传递策略类型

根据某个策略类型,执行某个策略逻辑

思路:需要保证某个类型对应某个策略类,通过springInitializingBean接口初始化bean,项目启动过程执行实现InitializingBean接口中的afterPropertiesSet方法,在这个方法中初始化map中指定的策略。

策略接口

public interface Strategy extends InitializingBean {BigDecimal quote(BigDecimal price);
}

策略工厂

package com.geekmice.springbootmybatiscrud.strategy.fourth;import org.springframework.stereotype.Component;import java.util.HashMap;
import java.util.Map;
import java.util.Objects;public class StrategyFactory {/*** 设置策略map*/private static Map<String, Strategy> strategyMap = new HashMap<>(16);public static Strategy getStrategyService(String type) {return strategyMap.get(type);}/*** 提前策略装入 strategyMap*/public static void register(String type, Strategy strategy) {if (Objects.isNull(type)) {return;}strategyMap.put(type, strategy);}
}

具体策略1

package com.geekmice.springbootmybatiscrud.strategy.fourth;import com.geekmice.springbootmybatiscrud.strategy.third.PayStrategy;
import org.springframework.stereotype.Component;import java.math.BigDecimal;
@Component
public class OrdinaryStrategy implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {
//        System.out.println("都要处理的内容");return price;}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("11111111111");StrategyFactory.register("1",this);}
}

具体策略2

package com.geekmice.springbootmybatiscrud.strategy.fourth;import com.geekmice.springbootmybatiscrud.strategy.third.PayStrategy;
import org.springframework.stereotype.Component;import java.math.BigDecimal;
@Component
public class GoldStrategy implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {BigDecimal res = price.multiply(new BigDecimal("0.8"));return res;}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("222222222222");StrategyFactory.register("2",this);}
}

具体策略3

package com.geekmice.springbootmybatiscrud.strategy.fourth;import com.geekmice.springbootmybatiscrud.strategy.third.PayStrategy;
import org.springframework.stereotype.Component;import java.math.BigDecimal;
@Component
public class PlatinumStrategy implements Strategy {@Overridepublic BigDecimal quote(BigDecimal price) {// 都要处理的内容// System.out.println("都要处理的内容");BigDecimal res = price.subtract(new BigDecimal("50")).multiply(new BigDecimal("0.7"));return res;}@Overridepublic void afterPropertiesSet() throws Exception {System.out.println("3333333333333");StrategyFactory.register("3",this);}}

测试

package com.geekmice.springbootmybatiscrud.controller;import com.geekmice.springbootmybatiscrud.dao.StudentMapper;
import com.geekmice.springbootmybatiscrud.pojo.Student;
import com.geekmice.springbootmybatiscrud.strategy.first.StrategyFactory;
import com.geekmice.springbootmybatiscrud.strategy.fourth.Strategy;
import org.springframework.web.bind.annotation.*;import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;/*** @author Administrator*/
@RestController
@RequestMapping("/student")
public class StudentController {@Resourceprivate StudentMapper studentMapper;@GetMapping(value = "queryAll")public List<Student> queryAll() {Strategy strategyService =StrategyFactory.getStrategyService("1");System.out.println(strategyService);System.out.println(strategyService.quote(new BigDecimal("1000")));return new ArrayList<>();}}

http://www.ppmy.cn/embedded/161892.html

相关文章

MT6835 21位 磁编码器 SPI 平台无关通用驱动框架 STM32

MT6835 21位 磁编码器 SPI 平台无关通用驱动框架 STM32 1. 获取代码&#xff1a;2. 加入你的项目2.1 以 STM32 为例:2.2 以 ESP-IDF 为例: 3. 对接 API3.1 以 STM32 为例&#xff1a; 4. 更多函数说明5. 写入 EEPROM 示例 MT6835 Framework 纯C语言实现&#xff0c;跨平台&…

【2024最新Java面试宝典】—— SpringBoot面试题(44道含答案)_java spingboot 面试题

37. 如何重新加载 Spring Boot 上的更改&#xff0c;而无需重新启动服务器&#xff1f;Spring Boot项目如何热部署&#xff1f;38. SpringBoot微服务中如何实现 session 共享 ?39. 您使用了哪些 starter maven 依赖项&#xff1f;40. Spring Boot 中的 starter 到底是什么 ?4…

手动配置IP

手动配置IP&#xff0c;需要考虑四个配置项&#xff1a; 四个配置项 IP地址、子网掩码、默认网关、DNS服务器 IP地址&#xff1a;格式表现为点分十进制&#xff0c;如192.168.254.1 子网掩码&#xff1a;用于区分网络位和主机位 【子网掩码的二进制表达式一定是连续的&#…

深入剖析 Apache Shiro550 反序列化漏洞及复现

目录 前言 一、认识 Apache Shiro 二、反序列化漏洞&#xff1a;隐藏在数据转换中的风险 三、Shiro550 漏洞&#xff1a;会话管理中的致命缺陷 四、漏洞危害&#xff1a;如多米诺骨牌般的连锁反应 五、漏洞复现&#xff1a;揭开攻击的神秘面纱 &#xff08;一&#xff0…

Linux内核实时机制x - 中断响应测试 Cyclictest分析1

Linux内核实时机制x - 中断响应测试Cyclitest 1 实时性测试工具 rt-test 1.1 源码下载 1.下载源码&#xff1a; ~/0-code/5.15$ git clone git://git.kernel.org/pub/scm/utils/rt-tests/rt-tests.git 正克隆到 rt-tests... remote: Enumerating objects: 5534, done. remot…

智能GUI Agent是什么,有什么应用领域

智能GUI Agent是什么 研究背景与目的:GUI长期主导人机交互,LLM特别是多模态模型的出现,为GUI自动化带来变革,催生了基于LLM的GUI智能体。这些智能体可理解自然语言指令,处理复杂GUI元素并执行操作,改变了用户与软件交互方式。论文旨在梳理该领域发展脉络,剖析关键要素,…

Django 项目自动化部署脚本全解析

在开发和部署 Django 项目时,我们经常需要执行一系列重复性的任务,如安装依赖、数据库迁移、创建管理员账号等。本文将详细介绍一个自动化部署脚本,帮助简化这些流程。 1. 脚本概述 1.1 主要功能 自动安装项目依赖执行数据库迁移创建超级管理员账号启动开发服务器提供详细…

在 Debian 12 中设置 Cron 作业(飞牛NAS定时自动重启实例)

在 Debian 12 中设置 Cron 作业是一个相对简单的过程&#xff0c;以下是详细的步骤和注意事项&#xff1a; 1. 安装 Cron Cron 通常在 Debian 系统中默认安装。如果未安装&#xff0c;可以通过以下命令安装&#xff1a; sudo apt-get update sudo apt-get install cron 2.…