设计模式之策略模式

目录

  • 背景
  • 步骤
    • 关于策略模式,他的业务需求是什么样的场景?
    • 什么是策略模式?
    • 当然策略模式的实现不仅仅是策略模式,他和简单工厂的设计模式有什么样的关系?
    • 方法是什么
  • 总结

背景

问题是最好的老师
关于策略模式,他的业务需求是什么样的场景?
当然策略模式的实现不仅仅是策略模式,他和简单工厂的设计模式有什么样的关系?
试想一下,如果把简单工厂换成工厂,方法又会发生怎样的变化? 反射又如何应用?
策略模式是如何一步一步衍化的?是依据什么样的思路进行衍化的,衍化的每一次升级发生了哪些巨大的变化?
在策略模式中所有的 Uml图是如何对应代码的?
通过对策略模式的整体学习,结构化分析以及相关的深入,你用一句话来描述一下策略模式是如何以一步一步演化到现在的需求,并展示一下未来的策略模式将会是什么样子? 通过对策略模式的整体性思考,我们来分析一下我们的智慧,是怎么样一步一步解决这些问题的,并且能够很自然的进行演化。 去思考一个 N+1的成长过程?描绘一下策略模式的n+1的每一步轨迹, N+1能够演变的内在动力是什么?

步骤

关于策略模式,他的业务需求是什么样的场景?

举个例子,商场中的收费模式分为:正常收费,打折,满减。可以使用策略模式实现。(这是我最开始的理解)
后来变成了类似方法的理解,入参只有一个入口,出参也只有一个出口。
也就是说我们要算钱的话,不管是按照哪种策略算钱,都是入参都是原价,出参都是最终付钱的价格。基于这样的业务条件,使用策略模式。

什么是策略模式?

策略模式(Strategy Pattern)是一种行为型设计模式,它允许在运行时选择算法的不同实现,并将其封装在独立的策略类中。这样可以使得算法的变化独立于使用它们的客户端。策略模式通过定义一系列算法,然后将其封装在各自的类中,使得这些算法可以相互替换,以满足不同的需求,同时不影响客户端的代码。

策略模式的主要参与者包括:

Context(上下文):上下文是客户端与策略之间的桥梁。它持有一个策略对象的引用,并在运行时切换不同的策略。上下文根据不同的情况或条件选择适当的策略进行调用。

Strategy(策略):策略是一个接口或抽象类,它定义了一组算法接口,各个具体策略类都实现这个接口。每个策略类封装了一种特定的算法。

使用策略模式的优点包括:

可扩展性:可以方便地增加新的策略类,扩展系统的功能,无需修改现有代码。

可维护性:由于不同的算法被封装在独立的策略类中,代码更加清晰和可维护。

代码复用:不同的上下文可以共享同一个策略,提高代码复用性。

当然策略模式的实现不仅仅是策略模式,他和简单工厂的设计模式有什么样的关系?

策略模式只有和简单工厂或者工厂方法结合才有意义,因为context类中才是具体各个子类之间产生关系的地方,而策略模式最重要的点就是Context类中让各个子类有逻辑关系,二者缺一不可。

首先展示效果
在这里插入图片描述

策略模式使用反射,带上配置文件

在这里插入图片描述

在这里插入图片描述


public class Client {

    public static void main(String[] args) throws Exception {
        Notice notice = new Notice();
        notice.notice();
    }
}

package com.example.designer20230731.Strategy1;

import java.io.FileInputStream;
import java.io.IOException;
import java.util.*;

public class Notice {
    class GetParam {
        private List<String> getParam() throws Exception {

            Scanner scanner = new Scanner(System.in);
            System.out.println("请输入算钱的方式,");
            String wayOfSum = scanner.nextLine();
            System.out.println("请输入总钱数");
            String sumOfMoney = scanner.nextLine();
            List<String> paramList = new ArrayList<>();
            paramList.add(wayOfSum);
            paramList.add(sumOfMoney);
            return paramList;

        }
    }


    public class ConfigUtil {
        public String get(String key) throws IOException {
            Properties properties = new Properties();
            properties.load(new FileInputStream("E:\\zy\\TGB-zgy-2022\\MiMust\\MiDesignDemo\\JAVAtest\\Designer20230731\\src\\main\\resources\\application.properties"));
            return properties.getProperty(key);
        }
    }
    private void compositeBusiness() throws Exception {
        while (true)
        {
        GetParam getParam = new GetParam();
        List<String> param = getParam.getParam();
        ConfigUtil configUtil = new ConfigUtil();
        String Way = String.valueOf(configUtil.get(param.get(0)));
        Context context = new Context(Way);
        Double aDouble = Double.valueOf((param.get(1)));
        context.contextInterface(aDouble);
    }
    }

    public void notice() throws Exception {

            this.compositeBusiness();



    }


}


package com.example.designer20230731.Strategy1;


public class Context {
//    Strategy  strategy;
//
//    public  Context( Strategy  strategy) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
//
//      this.strategy = strategy;
//    }
//
//
//    public void  contextInterface(double money){
//        strategy.acceptCash(money);
//    }
Strategy  strategy;

    public  Context( String  Way) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
        Class<?> wayClass = Class.forName(Way);
        Object instance = wayClass.newInstance();
        IFactory factory = (IFactory) instance;
        Strategy strategy1 = factory.createStrategy();
        this.strategy = strategy1;
    }


    public void  contextInterface(double money){
        strategy.acceptCash(money);
    }


}

public interface IFactory {
    Strategy createStrategy();

}


public class NormalFactory  implements   IFactory{
    
    public Strategy  createStrategy() {
      return     new CashNormal();
    }



}

public class RebateFactory  implements   IFactory{
    
    public Strategy createStrategy() {
        return  new CashRebate(0.8);
    }
}

public class RebateFactory  implements   IFactory{
    
    public Strategy createStrategy() {
        return  new CashRebate(0.8);
    }
}
public class ReturnFactory  implements   IFactory{
    
    public Strategy createStrategy() {
        return  new CashReturn(300,10);
    }
}
public   abstract class Strategy {

    public double acceptCash(double money) {
       return 0;
    }
}
public class CashNormal extends Strategy {
    
    public double acceptCash(  double  money) {
        System.out.println(money);
        return  money;
    }
}
package com.example.designer20230731.Strategy1;



public class CashRebate extends Strategy {

    double  moneyRebate = 0.8;

    public CashRebate(double moneyRebate){
        this.moneyRebate = moneyRebate;
    }

    
    public double acceptCash(  double  money) {
        System.out.println(money*moneyRebate);
            return money*moneyRebate;
    }
}

package com.example.designer20230731.Strategy1;


public class CashReturn extends Strategy {


    private double moneyCondition = 0.00;
    private double getMoneyReturn = 0.00;

    public CashReturn(double moneyCondition, double getMoneyReturn) {
        this.getMoneyReturn = getMoneyReturn;
        this.moneyCondition = moneyCondition;
    }

    
    public double acceptCash(double money) {
        double result = money;
//        double init = money;
        if (money > moneyCondition) {
             result = money - getMoneyReturn;
            System.out.println(result);
            return result;

        }
        System.out.println(result);
        return result;
    }

}

配置文件

CashNormal=com.example.designer20230731.Strategy1.NormalFactory
CashRebate=com.example.designer20230731.Strategy1.RebateFactory

方法是什么

方法是一个黑匣子,我们只关注入参和出参,并不关注具体如何实现,对应到策略模式上就是我们的客户端只关注Context类 并不关注Context中是如何实现的,

总结

从一开始按照原价付费
到后来能够打折
到后来能够满减
策略模式可以解决人们日益增长的需求,从有限需求要无限需求的跨越,使用面向对象的思考方式都能解决。

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

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

相关文章

springboot文件上传和下载接口的简单思路

springboot文件上传和下载的简单思路 文件上传文件下载 文件上传 在springboot中&#xff0c;上传文件只需要在接口中通过 MultipartFile 对象来获取前端传递的数据&#xff0c;然后将数据存储&#xff0c;并且返回一个对外访问路径即可。一般对于上传文件的文件名&#xff0c…

在 Android 上使用机器学习套件检测人脸

须知事项 此 API 需要 Android API 级别 19 或更高级别。确保应用的 build 文件使用的 minSdkVersion 值不小于 19。 请务必在您的项目级 build.gradle 文件中的 buildscript 和 allprojects 部分添加 Google 的 Maven 代码库。 将 Android 版机器学习套件库的依赖项添加到模…

【MATLAB第68期】基于MATLAB的LSTM长短期记忆网络多变量时间序列数据多步预测含预测未来(非单步预测)

【MATLAB第68期】基于MATLAB的LSTM长短期记忆网络多变量时间序列数据多步预测含预测未来&#xff08;非单步预测&#xff09; 输入前25个时间&#xff0c;输出后5个时间 一、数据转换 1、原始数据 5列时间序列数据&#xff0c;70行样本 705 数据矩阵结构 2、数据转换 将…

【论文阅读】NoDoze:使用自动来源分类对抗威胁警报疲劳(NDSS-2019)

NODOZE: Combatting Threat Alert Fatigue with Automated Provenance Triage 伊利诺伊大学芝加哥分校 Hassan W U, Guo S, Li D, et al. Nodoze: Combatting threat alert fatigue with automated provenance triage[C]//network and distributed systems security symposium.…

2023/8/11题解

时间限制: 1000MS 内存限制: 65536KB 解题思路 建树 模拟 &#xff0c;复杂在于建树&#xff0c;此处从题目需求可知需要按层建树&#xff0c;所以需要队列模拟&#xff0c;查找比较容易就是普通的深搜 参考代码 #include<bits/stdc.h> using namespace std; vector<…

Windows 环境下 Python3 离线安装 cryptography 失败

发布Flask Web项目时&#xff0c;报错缺少Cryptography&#xff0c;于是尝试重新安装该库&#xff0c;但本机没有网络&#xff0c;只支持手动离线安装&#xff0c;尝试了pip、setup.py两种方式安装&#xff0c;结果都报错。。最后使用将安装包拷贝至本机(在其他电脑上安装的sit…

【算法挨揍日记】day01——双指针算法_移动零、 复写零

283.移动零 283. 移动零https://leetcode.cn/problems/move-zeroes/ 题目&#xff1a; 给定一个数组 nums&#xff0c;编写一个函数将所有 0 移动到数组的末尾&#xff0c;同时保持非零元素的相对顺序。 请注意 &#xff0c;必须在不复制数组的情况下原地对数组进行操作。 …

gitee分支合并

合并dev分支到master&#xff08;合并到主分支&#xff09; git checkout master git merge dev //这里的dev表示你的分支名称 git push //推送到远程仓库 效果如下图 不报错就表示推送成功了&#xff0c;希望能帮助各位小伙伴

DevOps最佳实践和工具在本地环境中的概述

引言 最近&#xff0c;我进行了一次网上搜索&#xff0c;以寻找DevOps的概述&#xff0c;尽管有大量的DevOps工具和实践&#xff0c;但我无法找到一个综合的概述。因此&#xff0c;我开始了对DevOps生态系统和最佳实践的梳理&#xff0c;以创建一个整体视图,方便后续研究实践 C…

5.1 web浏览安全

数据参考&#xff1a;CISP官方 目录 Web应用基础浏览器所面临的安全威胁养成良好的Web浏览安全意识如何安全使用浏览器 一、Web应用基础 1、Web应用的基本概念 Web ( World wide Web) 也称为万维网 脱离单机Web应用在互联网上占据了及其重要的地位Web应用的发展&#xf…

K8s环境下监控告警平台搭建及配置

Promethues是可以单机搭建的&#xff0c;参考prometheus入门[1] 本文是就PromethuesGrafana在K8s环境下的搭建及配置 Prometheus度量指标监控平台简介 启动minikube minikube start 安装helm 使用Helm Chart 安装 Prometheus Operator: helm install prometheus-operator stabl…

AI:01-基于机器学习的深度学习的玫瑰花种类的识别

文章目录 一、数据集介绍二、数据预处理三、模型构建四、模型训练五、模型评估六、模型训练七、模型评估八、总结深度学习技术在图像识别领域有着广泛的应用,其中一种应用就是玫瑰花种类的识别。在本文中,我们将介绍如何使用机器学习和深度学习技术来实现玫瑰花种类的识别,并…

备忘录模式(C++)

定义 在不破坏封装性的前提下&#xff0c;捕获一-个对象的内部状态&#xff0c;并在该对象之外保存这个状态。这样以后就可以将该对象恢复到原先保存的状态。 应用场景 ➢在软件构建过程中&#xff0c;某些对象的状态在转换过程中&#xff0c;可能由于某种需要&#xff0c;要…

c++遍历当前windows目录

前言 设置vs的高级属性为使用多字节字符集&#xff0c;不然会报char类型的实参与LPCWSTR类型的形参类型不兼容的错误 代码 #include <iostream> #include <cstring> #include <windows.h>void listFiles(const char* dir);int main() {using namespace st…

【服务平台】Rancher运行和管理Docker和Kubernetes,提供管理生产中的容器所需的整个软件堆栈

Rancher是一个开源软件平台&#xff0c;使组织能够在生产中运行和管理Docker和Kubernetes。使用Rancher&#xff0c;组织不再需要使用一套独特的开源技术从头开始构建容器服务平台。Rancher提供了管理生产中的容器所需的整个软件堆栈。  完整软件堆栈 Rancher是供采用容器的团…

SpringBoot案例-部门管理-删除

目录 查看页面原型&#xff0c;明确需求 页面原型 需求 阅读接口文档 思路分析 功能接口开发 控制层&#xff08;Controllre类&#xff09; 业务层&#xff08;Service类&#xff09; 持久层&#xff08;Mapper类&#xff09; 接口测试 前后端联调 查看页面原型&a…

NIDS网络威胁检测系统-Golang

使用技术&#xff1a; Golang Gin框架 前端三件套 演示画面&#xff1a; 可以部署在linux和window上 目前已在Kali2021和Window10上进行测试成功

【瑞吉外卖】Linux学习

Linux常用命令 Linux命令初体验 Linux的命令都是由一个或几个单词的缩写构成的 命令对应英文作用lslist查看当前目录下的内容pwdprint work directory查看当前所在目录cd [目录名]change directory切换目录touch [文件名]touch如果文件不存在&#xff0c;新建文件mkdir [目录…

Redis_哨兵模式

9. 哨兵模式 9.1 简介 当主库宕机&#xff0c;在从库中选择一个&#xff0c;切换为主库。 问题: 主库是否真正宕机?哪一个从库可以作为主库使用?如何实现将新的主库的信息通过给从库和客户端&#xff1f; 9.2 基本流程 哨兵主要任务&#xff1a; 监控选择主库通知 会有…

JavaWeb-Servlet服务连接器(一)

目录 1.Servlet生命周期 2.Servlet的配置 3.Servlet的常用方法 4.Servlet体系结构 5.HTTP请求报文 6.HTTP响应报文 1.Servlet生命周期 Servlet&#xff08;Server Applet&#xff09;是Java Servlet的简称。其主要的功能是交互式地浏览和修改数据&#xff0c;生成一些动态…