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

项目场景:

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

示例:商城系统有会员系统,不同会员有不同优惠程度,普通会员不优惠;黄金会员打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.mzph.cn/news/895303.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Android ndk兼容 64bit so报错

1、报错logcat如下 2025-01-13 11:34:41.963 4687-4687 DEBUG pid-4687 A #01 pc 00000000000063b8 /system/lib64/liblog.so (__android_log_default_aborter16) (BuildId: 467c2038cdfa767245f9280e657fdb85) 2025…

centos安装Nexus Repository OSS(Maven私服)

1. 下载链接&#xff1a;https://help.sonatype.com/en/download.html 2. 注意页面下载页面中的要求&#xff1a;JDK17&#xff08;启动时提示最低JDK1.8最高JDK17&#xff0c;但是使用JDK1.8无法正常启动&#xff09; 3. mkdir /opt/nexus 将压缩包上传到该目录并解压。 tar …

b站——《【强化学习】一小时完全入门》学习笔记及代码(1-3 多臂老虎机)

问题陈述 我们有两个多臂老虎机&#xff08;Multi-Armed Bandit&#xff09;&#xff0c;分别称为左边的老虎机和右边的老虎机。每个老虎机的奖励服从不同的正态分布&#xff1a; 左边的老虎机&#xff1a;奖励服从均值为 500&#xff0c;标准差为 50 的正态分布&#xff0c;即…

Linux:安装 node 及 nvm node 版本管理工具(ubuntu )

目录 方法一&#xff1a;手动下载安装文件安装方法二&#xff1a;curl安装 方法一&#xff1a;手动下载安装文件安装 git clone 远程镜像 git clone https://gitee.com/mirrors/nvm安装 nvm bash install.sh刷新配置&#xff0c;使配置在终端生效 // 方法 1 source /root/.…

基于STM32的ADS1230驱动例程

自己在练手项目中用到了ADS1230&#xff0c;根据芯片手册自写的驱动代码&#xff0c;已测可用&#xff0c;希望对将要用到ADS1230芯片的人有所帮助。 芯片&#xff1a;STM32系列任意芯片、ADS1230 环境&#xff1a;使用STM32CubeMX配置引脚、KEIL 部分电路&#xff1a; 代码…

游戏引擎学习第98天

仓库:https://gitee.com/mrxiao_com/2d_game_2 开始进行一点回顾 今天的目标是继续实现正常贴图的操作&#xff0c;尽管目前我们还没有足够的光照信息来使其完全有用。昨日完成了正常贴图相关的基础工作&#xff0c;接下来将集中精力实现正常贴图的基本操作&#xff0c;并准备…

Windows 本地部署大模型 OpenWebUI+Ollama

安装Ollama Ollama官方网址&#xff1a;https://ollama.com 下载运行大模型 在Ollama官网中查看需要下载的大模型 https://ollama.com/library 复制图片中的链接 打开cmd&#xff0c;运行此命令&#xff08;此过程会时间会很久&#xff09; 下载Miniconda Miniconda作用是…

npm运行Vue项目报错 error:0308010c:digital envelope routines::unsupported

大家好&#xff0c;我是 程序员码递夫。 问题 VSCode 运行Vue项目&#xff0c;提示错误&#xff1a; building 2/2 modules 0 activeError: error:0308010c:digital envelope routines::unsupported 解决方法 原因是 npm 高版本(大于17)&#xff0c;对ssl的处理做了改进&…

安川伺服控制器MP系列优势特点及行业应用

在工业自动化领域&#xff0c;运动控制器的性能直接决定了设备的精度、效率和可靠性。作为全球领先的运动控制品牌&#xff0c;安川电机伺服控制器凭借其卓越的技术优势和广泛的应用场景&#xff0c;正在为智能制造注入强劲动力&#xff01; MP3100&#xff1a;主板型运动控制…

Python----PyQt开发(PyQt高级:图像显示,定时器,进度条)

一、图像显示 1.1、增加图标 1.直接创建setWindowIcon(QIcon(灯泡.jpg)) import sys from PyQt5.QtWidgets import QApplication, QMainWindow, QPushButton from PyQt5.QtGui import QIconclass MainWindow(QMainWindow):def __init__(self):super(MainWindow, self).__init_…

工业路由器物联网应用,智慧环保环境数据监测

在智慧环保环境数据监测中工业路由器能连接各类分散的传感器&#xff0c;实现多源环境数据集中采集&#xff0c;并通过多种通信网络稳定传输至数据中心或云平台。 工作人员借助工业路由器可远程监控设备状态与环境数据&#xff0c;还能远程配置传感器参数。远程控制设置数据阈…

【DeepSeek】在本地计算机上部署DeepSeek-R1大模型实战(完整版)

【作者主页】Francek Chen 【专栏介绍】 ⌈ ⌈ ⌈人工智能与大模型应用 ⌋ ⌋ ⌋ 人工智能&#xff08;AI&#xff09;通过算法模拟人类智能&#xff0c;利用机器学习、深度学习等技术驱动医疗、金融等领域的智能化。大模型是千亿参数的深度神经网络&#xff08;如ChatGPT&…

JAVA并发编程3--多线程程序

​ 1.创建线程的方法&#xff1a; 案例&#xff1a;计算1-1000的整数和 实现Runnable接口 步骤&#xff1a; 1.创建一个实现了Runnable接口的类 2.实现类去实现Runnable中的抽象方法&#xff1a;run() 3.创建实现类的对象 4.将此对象作为参数传递到Thread类的构造器中&#…

django中间件,中间件给下面传值

1、新建middleware.py文件 # myapp/middleware.py import time from django.http import HttpRequest import json from django.http import JsonResponse import urllib.parse class RequestTimeMiddleware:def __init__(self, get_response):self.get_response get_respons…

Vision Transformer:打破CNN垄断,全局注意力机制重塑计算机视觉范式

目录 引言 一、ViT模型的起源和历史 二、什么是ViT&#xff1f; 图像处理流程 图像切分 展平与线性映射 位置编码 Transformer编码器 分类头&#xff08;Classification Head&#xff09; 自注意力机制 注意力图 三、Coovally AI模型训练与应用平台 四、ViT与图像…

深入浅出:探索 DeepSeek 的强大功能与应用

深入浅出&#xff1a;探索 DeepSeek 的强大功能与应用 在人工智能技术飞速发展的今天&#xff0c;自然语言处理&#xff08;NLP&#xff09;作为其重要分支&#xff0c;正逐渐渗透到我们生活的方方面面。DeepSeek 作为一款功能强大的 NLP 工具&#xff0c;凭借其易用性和高效性…

轮子项目--消息队列的实现(3)

上一篇文章中我把一些关键的类以及表示出来&#xff0c;如何对这些类对应的对象进行管理呢&#xff1f;管理分为硬盘和内存上&#xff0c;硬盘又分为数据库&#xff08;管理交换机&#xff0c;队列和绑定&#xff09;和文件&#xff08;管理消息&#xff09;&#xff0c;本文就…

【转载】开源鸿蒙OpenHarmony社区运营报告(2025年1月)

●截至2025年1月31日&#xff0c;开放原子开源鸿蒙&#xff08;OpenAtom OpenHarmony&#xff0c;简称“开源鸿蒙”或“OpenHarmony”&#xff09;社区累计超过8200名贡献者&#xff0c;共63家成员单位&#xff0c;产生51.2万多个PR、2.9万多个Star、10.5万多个Fork、68个SIG。…

双周报Vol.65:新增is表达式、字符串构造和数组模式匹配增强、IDE模式匹配补全增强...多项技术更新!

MoonBit更新 新增 is 表达式 这个表达式的语法形式为 expr is pat&#xff0c;这个表达式为 Bool 类型&#xff0c;当 expr 符合 pat 这个模式的时候返回 true&#xff0c;比如&#xff1a; fn use_is_expr(x: Int?) -> Unit {if x is Some(i) && i > 10 { .…

百问网imx6ullpro调试记录(linux+qt)

调试记录 文章目录 调试记录进展1.开发板相关1.1百问网乌班图密码 1.2 换设备开发环境搭建串口调试网络互通nfs文件系统挂载 1.3网络问题1.4系统启动1.5进程操作 2.QT2.1tslib1.获取源码2.安装依赖文件3.编译 2.2qt移植1.获取qt源码2.配置编译器3.编译 2.3拷贝到开发板1.拷贝2.…