问题:通过策略模式+工厂模式+模板方法模式实现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{
    @Override
    public 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{
    @Override
    public 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 {
    @Override
    public 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{
    @Override
    public 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
        this.exec();
        return price;
    }

    @Override
    public 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
        BigDecimal res = price.multiply(new BigDecimal("0.8"));
        this.exec();
        return res;
    }

    @Override
    public 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
        BigDecimal res = price.subtract(new BigDecimal("50")).multiply(new BigDecimal("0.7"));
        return res;
    }

    @Override
    public 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 {
    @Resource
    private 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
//        System.out.println("都要处理的内容");
        return price;
    }

    @Override
    public 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
        BigDecimal res = price.multiply(new BigDecimal("0.8"));
        return res;
    }

    @Override
    public 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 {
    @Override
    public BigDecimal quote(BigDecimal price) {
        // 都要处理的内容
        // System.out.println("都要处理的内容");
        BigDecimal res = price.subtract(new BigDecimal("50")).multiply(new BigDecimal("0.7"));
        return res;
    }

    @Override
    public 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 {
    @Resource
    private 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<>();

    }

}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/968219.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

Android Studio2024版本安装环境SDK、Gradle配置

一、软件版本&#xff0c;安装包附上 &#x1f449;android-studio-2024.1.2.12-windows.exe&#x1f448; &#x1f449;百度网盘Android Studio安装包&#x1f448; &#xff08;若下载连链接失效可去百度网盘链接下载&#xff09; 二、软件安装过程 ​ ​ ​ 三、准备运行…

Leetcode - 149双周赛

目录 一、3438. 找到字符串中合法的相邻数字二、3439. 重新安排会议得到最多空余时间 I三、3440. 重新安排会议得到最多空余时间 II四、3441. 变成好标题的最少代价 一、3438. 找到字符串中合法的相邻数字 题目链接 本题有两个条件&#xff1a; 相邻数字互不相同两个数字的的…

使用 meshgrid函数绘制网格点坐标的原理与代码实现

使用 meshgrid 绘制网格点坐标的原理与代码实现 在 MATLAB 中&#xff0c;meshgrid 是一个常用函数&#xff0c;用于生成二维平面网格点的坐标矩阵。本文将详细介绍如何利用 meshgrid 函数生成的矩阵绘制网格点的坐标&#xff0c;并给出具体的代码实现和原理解析。 实现思路 …

【AI赋能】蓝耘智算平台实战指南:3步构建企业级DeepSeek智能助手

蓝耘智算平台实战指南&#xff1a;3步构建企业级DeepSeek智能助手 引言&#xff1a;AI大模型时代的算力革命 在2025年全球AI技术峰会上&#xff0c;DeepSeek-R1凭借其开源架构与实时推理能力&#xff0c;成为首个通过图灵测试的中文大模型。该模型在语言理解、跨模态交互等维…

Mac(m1)本地部署deepseek-R1模型

1. 下载安装ollama 直接下载软件&#xff0c;下载完成之后&#xff0c;安装即可&#xff0c;安装完成之后&#xff0c;命令行中可出现ollama命令 2. 在ollama官网查看需要下载的模型下载命令 1. 在官网查看deepseek对应的模型 2. 选择使用电脑配置的模型 3. copy 对应模型的安…

第七节 文件与流

基本的输入输出&#xff08;iostream&#xff09; C标准库提供了一组丰富的输入/输出功能&#xff0c;C的I/O发生在流中&#xff0c;流是字节序列。如果字节流是从设备&#xff08;键盘、磁盘驱动器、网络连接等&#xff09;流向内存&#xff0c;叫做输入操作。如果字节流是从…

网络安全溯源 思路 网络安全原理

网络安全背景 网络就是实现不同主机之间的通讯。网络出现之初利用TCP/IP协议簇的相关协议概念&#xff0c;已经满足了互连两台主机之间可以进行通讯的目的&#xff0c;虽然看似简简单单几句话&#xff0c;就描述了网络概念与网络出现的目的&#xff0c;但是为了真正实现两台主机…

内网ip网段记录

1.介绍 常见的内网IP段有&#xff1a; A类&#xff1a; 10.0.0.0/8 大型企业内部网络&#xff08;如 AWS、阿里云&#xff09; 10.0.0.0 - 10.255.255.255 B类&#xff1a;172.16.0.0/12 中型企业、学校 172.16.0.0 - 172.31.255.255 C类&#xff1a;192.168.0.0/16 家庭…

SQL Server 逻辑查询处理阶段及其处理顺序

在 SQL Server 中&#xff0c;查询的执行并不是按照我们编写的 SQL 语句的顺序进行的。相反&#xff0c;SQL Server 有自己的一套逻辑处理顺序&#xff0c;这个顺序决定了查询的执行方式和结果集的生成。了解这些处理阶段和顺序对于优化查询性能和调试复杂查询非常重要。 SQL …

四、OSG学习笔记-基础图元

前一章节&#xff1a; 三、OSG学习笔记-应用基础-CSDN博客https://blog.csdn.net/weixin_36323170/article/details/145514021 代码&#xff1a;CuiQingCheng/OsgStudy - Gitee.com 一、绘制盒子模型 下面一个简单的 demo #include<windows.h> #include<osg/Node&…

性格测评小程序03搭建用户管理

目录 1 创建数据源2 搭建后台3 开通权限4 搭建启用禁用功能最终效果总结 性格测评小程序我们期望是用户先进行注册&#xff0c;注册之后使用测评功能。这样方便留存用户的联系信息&#xff0c;日后还可以推送对应的相关活动促进应用的活跃。实现这个功能我们要先创建数据源&…

Ubuntu 如何安装Snipaste截图软件

在Ubuntu上安装Snipaste-2.10.5-x86_64.AppImage的步骤如下&#xff1a; 1. 下载Snipaste AppImage 首先&#xff0c;从Snipaste的官方网站或GitHub Releases页面下载Snipaste-2.10.5-x86_64.AppImage文件。 2. 赋予执行权限 下载完成后&#xff0c;打开终端并导航到文件所在…

突破与重塑:逃离Java舒适区,借Go语言复刻Redis的自我突破和成长

文章目录 写在文章开头为什么想尝试用go复刻redis复刻redis的心路历程程序员对于舒适区的一点看法关于mini-redis的一些展望结语 写在文章开头 在程序员的技术生涯长河中&#xff0c;我们常常会在熟悉的领域中建立起自己的“舒适区”。于我而言&#xff0c;Java 就是这片承载…

【自然语言处理】TextRank 算法提取关键词、短语、句(Python源码实现)

文章目录 一、TextRank 算法提取关键词 [工具包]二、TextRank 算法提取关键短语[工具包]三、TextRank 算法提取关键句[工具包]四、TextRank 算法提取关键句&#xff08;Python源码实现&#xff09; 一、TextRank 算法提取关键词 [工具包] 见链接 【自然语言处理】TextRank 算法…

展厅为何倾向使用三维数字沙盘进行多媒体互动设计?优势探讨!

随着数字技术的迅猛进步&#xff0c;展厅多媒体互动设计正迎来深刻变革。其中&#xff0c;三维数字沙盘作为经典沙盘模型的革新之作&#xff0c;不仅保留了其空间布局直观展示的优点&#xff0c;更巧妙融入光影互动与中控系统&#xff0c;推动展览展示向智能化迈进。今日&#…

SDKMAN! 的英文全称是 Software Development Kit Manager(软件开发工具包管理器)

文章目录 SDKMAN! 的核心功能SDKMAN! 的常用命令SDKMAN! 的优势总结 SDKMAN! 的英文全称是 Software Development Kit Manager。它是一个用于管理多个软件开发工具&#xff08;如 Java、Groovy、Scala、Kotlin 等&#xff09;版本的工具。SDKMAN! 提供了一个简单的方式来安装、…

java配置api,vue网页调用api从oracle数据库读取数据

一、主入口文件 1&#xff1a;java后端端口号 2&#xff1a;数据库类型 和 数据库所在服务器ip地址 3&#xff1a;服务器用户名和密码 二、映射数据库表中的数据 resources/mapper/.xml文件 1&#xff1a;column后变量名是数据库中存储的变量名 property的值是column值的…

蓝桥杯C语言组:分治问题研究

蓝桥杯C语言组分治问题研究 摘要 本文针对蓝桥杯C语言组中的分治问题展开深入研究&#xff0c;详细介绍了分治算法的原理、实现方法及其在解决复杂问题中的应用。通过对经典例题的分析与代码实现&#xff0c;展示了分治算法在提高编程效率和解决实际问题中的重要作用&#xff…

Golang GORM系列:GORM CRUM操作实战

在数据库管理中&#xff0c;CRUD操作是应用程序的主干&#xff0c;支持数据的创建、检索、更新和删除。强大的Go对象关系映射库GORM通过抽象SQL语句的复杂性&#xff0c;使这些操作变得轻而易举。本文是掌握使用GORM进行CRUD操作的全面指南&#xff0c;提供了在Go应用程序中有效…

如何评估云原生GenAI应用开发中的安全风险(下)

以上就是如何评估云原生GenAI应用开发中的安全风险系列中的上篇内容&#xff0c;在本篇中我们介绍了在云原生AI应用开发中不同层级的风险&#xff0c;并了解了如何定义AI系统的风险。在本系列下篇中我们会继续探索我们为我们的云原生AI应用评估风险的背景和意义&#xff0c;并且…