spring项目中使用策略模式

news2024/9/29 18:49:25

小白看了Java设计模式一书,晕晕乎乎,好像懂了,又好像啥都没懂。对照着书本一行行手打代码,完毕,执行,ok,设计模式已掌握。但到了项目中却又茫然。
小白我啊,今天尝试一下在自己的demo项目中使用策略模式,手动狗头。
我们要做什么,首先得知道它是什么吗,让我们使用bing来搜索,bing来搜索,并来搜索(重要的事情说三遍,ps:反正不要用baidu)

来自菜鸟教程
在这里插入图片描述小白具象一下,咱去饭店吃饭,对着菜单咔咔点,上菜了桌面有蒸羊羔、蒸熊掌、蒸鹿尾儿(小白搁着“报蔡明”呢);银耳羹;一大瓶可乐;还要了一大碗米饭;
小白和他那个假设存在的女朋友小红要吃饭了啊。那么小白想吃一口蒸熊掌,小白用筷子夹一了块,津津有味的吃起来了;小红想喝一口银耳羹,小红用勺子舀了一勺文雅的送入了樱桃小口;小白突然噎住了,还好还好,有大瓶可乐,于是小白赶忙摆好杯子倒上了满满一杯可乐,猛喝一大口,呼呼,舒服。
小白吃饱喝足了,要开始分解了。在这个模型中,小白吃饭是明确目的,但是吃的东西会有很多,不一样的菜可能会用到不一样的餐具,假设这家饭店只有筷子,小白会不会为了吃到银耳羹而在吃完了蒸熊掌后换一家有勺子的店呢,那如果需要几十种餐具才能吃的饭,岂不是要跑几十家?
在这个模型中,我们将小白的行为抽离出来并映射到策略模式中:
1)小白吃饭是整体目的
2)小白先吃什么,是一种策略(可以理解为后面用什么吃的前提行为,代码中就是if里面的判断)
3)这个店家有各种菜不同餐具(提供给小白选择的平台,小白不用关心怎么做的,餐具哪里买的)

模型说完,接下来用代码来实现

首先是一个通用接口

package com.example.demo.service;

/**
 * @author Niezj
 */
public interface EatFoodService {

    /**
     * 小白如何吃到这道菜
     * @param object 传入参数,自己根据业务进行修改
     * @return 返回信息 自己根基业务需要自己修改
     * */
    String eatFoodBehavior(Object object);

    /**
     * 小白要吃的这道菜的名字
     *
     * @return string (菜名字)
     * */
    String eatFoodName();
}

接下来是几个不同的实现类
1)吃蒸熊掌

package com.example.demo.service.impl;

import com.example.demo.service.EatFoodService;
import org.springframework.stereotype.Service;

/**
 * @author Niezj
 * 吃蒸熊掌
 */
@Service
public class EatFoodBearHandServiceImpl implements EatFoodService {
    @Override
    public String eatFoodBehavior(Object object) {
        System.out.println("\n");
        System.out.println("\n");
        System.out.println("小白用筷子夹了一块蒸熊掌,并说到,真好吃");
        System.out.println("\n");
        return "吃蒸熊掌";
    }

    @Override
    public String eatFoodName() {
        //demo 使用,具体业务请严谨命名
        return "蒸熊掌";
    }
}

2)喝银耳羹

package com.example.demo.service.impl;

import com.example.demo.service.EatFoodService;
import org.springframework.stereotype.Service;

/**
 * @author Niezj
 * 银耳羹具体实现类
 */
@Service
public class EatFoodTremellaSoupServiceImpl implements EatFoodService {
    @Override
    public String eatFoodBehavior(Object object) {
        System.out.println("\n");
        System.out.println("\n");
        System.out.println("(小白假设的女朋友)小红和了一口银耳羹");
        System.out.println("\n");
        return "喝银耳羹";
    }

    @Override
    public String eatFoodName() {
        //demo 使用,具体业务请严谨命名
        return "银耳羹";
    }
}

3)喝可乐

package com.example.demo.service.impl;

import com.example.demo.service.EatFoodService;
import org.springframework.stereotype.Service;

/**
 * @author Niezj
 * 大佬喝阔乐
 */
@Service
public class EatFoodCokeServiceImpl implements EatFoodService {
    @Override
    public String eatFoodBehavior(Object object) {
        System.out.println("\n");
        System.out.println("\n");
        System.out.println("小白吨吨吨喝了一瓶可乐,然后嗝了一声");
        System.out.println("\n");
        return "喝可乐";
    }

    @Override
    public String eatFoodName() {
        //demo 使用,具体业务请严谨命名
        return "可乐";
    }
}

4)最后来一个没钱只能吃大米饭就蒜的默认实现类

package com.example.demo.service.impl;

import com.example.demo.service.EatFoodService;
import org.springframework.stereotype.Service;

/**
 * @author Niezj
 * 小白因为没带钱,只能吃大米饭就大蒜了
 */
@Service
public class EatFoodRiceServiceImpl implements EatFoodService {
    @Override
    public String eatFoodBehavior(Object object) {
        System.out.println("\n");
        System.out.println("\n");
        System.out.println("小白摸摸口袋,对老板说来一碗米饭不要钱的蒜来两头");
        System.out.println("\n");
        return "吃大米饭就蒜";
    }

    @Override
    public String eatFoodName() {
        //demo 使用,具体业务请严谨命名
        return "大米饭就蒜";
    }
}

将以上实现类封装到一个全局唯一的map当中(承上启下的文件)

package com.example.demo.config;

import com.example.demo.service.DesignService;
import com.example.demo.service.EatFoodService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;
import java.util.HashMap;
import java.util.Map;

/**
 * @author Niezj
 */
@Component
public class EatFoodConfig {

    @Resource
    private ApplicationContext applicationContext;

    @Qualifier("eatFoodRiceServiceImpl")
    @Autowired
    private EatFoodService eatFoodService;

    /**
     * 全局唯一eatFood实现类型map
     */
    public static final Map<String, EatFoodService> EAT_FOOD_SERVICE_MAP = new HashMap<>(16);


    /**
     * 项目启动的时候先去将所有实现了吃饭的文件获取到并放到全局唯一的一个map中
     */
    @PostConstruct
    public void getAllFood() {
        Map<String, EatFoodService> models = applicationContext.getBeansOfType(EatFoodService.class);
        models.forEach((k, v) -> {
            EatFoodService eatFoodService = applicationContext.getBean(k, EatFoodService.class);
            // 自定义业务字典code,用于key的名称
            String serviceName = eatFoodService.eatFoodName();
            if (StringUtils.isNotBlank(serviceName)) {
                EAT_FOOD_SERVICE_MAP.put(serviceName, eatFoodService);
            }
        });
    }

    /**
     *
     * 开放接口,提供输入判断该什么菜用什么吃,具体的策略实现
     *
     */
    public Object selectEatFood(String eatFoodName,Object obj){
        // map获取,给定一个默认的实现,防止空指针异常
        // 具体业务具体实现,自己修改返回信息
        return EAT_FOOD_SERVICE_MAP.getOrDefault(eatFoodName,eatFoodService).eatFoodBehavior(obj);
    }



}

以上完成策略模式
那么赶紧来看看具体实现效果吧 ,写一个Controller

package com.example.demo.controller;

import com.example.demo.config.EatFoodConfig;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author ADMIN
 */
@RestController
public class EatFoodController {



    @Autowired
    private EatFoodConfig eatFoodConfig;

    @GetMapping("eatFood")
    public void eatFood(String eatFoodName) {
        Object obj = new Object();
        eatFoodConfig.selectEatFood(eatFoodName, obj);
    }


}

调用接口看一下正不正确,我们先输入蒸熊掌,然后喝银耳羹,再喝可乐,最后胡乱输一个字符串看看能不能吃大米饭
1 蒸熊掌
在这里插入图片描述2 银耳羹
在这里插入图片描述3 喝可乐
在这里插入图片描述4 测试一下我们兜底的吃大米饭会不会生效,这里设置了当输入的策略名称找不到对应的实现时候吃大米饭当实现

在这里插入图片描述以上完成策略模式的简单实现。
最后引用高中写作文给出的小故事:
国内最大日化公司引进了一条国外肥皂生产线。这条生产线能将肥皂从原材料的加入直到包装装箱自动完成。
但是,意外发生了。销售部门反映有的肥皂盒是空的。于是,这家公司立刻停止了生产线,并与生产线制造商取得联系。得知这种情况在设计上是无法避免的。
经理要求工程师们解决这个问题。于是成立一个以几名博士为核心、十几名研究生为骨干的团队。知识类型涉及光学、图像识别、自动化控制、机械设计等等门类。
在耗费数十万后,工程师们在生产线上一套X光机和高分辨率监视器,当机器对X光图像进行识别后,一条机械臂会自动将空盒从生产线上拿走。
另外一家私人企业司也遇到了同样的情况,老板对管理生产线的小工说:你一定要解决这个问题。于是这个小工找来一台电风扇,摆在生产线旁,另一端放上一个箩筐。装肥皂的盒子逐一在风扇前通过,只要有空盒子便会被吹离生产线,掉在箩筐里。 问题解决之。
两种做法并没有错,我们不能批判说小成本能解决的问题花这么多钱,毕竟不同的处境有不同的做法不是吗?

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

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

相关文章

【思科设备,最常用的命令是下面这些吗!】

​在调试思科设备时&#xff0c;我们会经常使用各种命令去实现&#xff0c;但是使用最为频繁的有哪些&#xff1f;我们来看看下面频繁出现但是又非常有用且常用的命令&#xff01; 1、&#xff1f; 在使用命令行时&#xff0c;我们不可能记住所有的命令&#xff0c;有时候只能…

git的一些常用指令

1&#xff09;拷贝一个 Git 仓库到本地&#xff0c;让自己能够查看该项目&#xff0c;或者进行修改。 git clone 远程git仓库地址2&#xff09;初始化本地git仓库。 git init 3&#xff09;监控工作区的状态树&#xff0c;会把工作时的所有变化提交到暂存区&#xff0c;这里…

(七)、首页列表数据渲染【uniapp+uinicloud多用户社区博客实战项目(完整开发文档-从零到完整项目)】

1&#xff0c;获取首页列表数据 1.1在index页面中编写从数据库中获取首页列表数据的方法 //获取首页列表数据getData() {let artTemp db.collection("quanzi_articles").getTemp();let userTemp db.collection("uni-id-users").field("_id,usernam…

智慧校园人脸识别系统源码

智慧校园人脸识别系统源码 技术架构&#xff1a; 后端&#xff1a;Java 框架&#xff1a;springboot 前端页面&#xff1a;vue element-ui 小程序&#xff1a;小程序原生开发 电子班牌&#xff1a;Java Android 源码有演示&#xff0c;可正常上线运营可授权。 随着智慧校…

在成都的哪个培训机构学习Java好呢?

自从小课06年进入成都这个IT培训市场以来&#xff0c;短短十几年&#xff0c;招过很多学员&#xff0c;也见证过很多机构的起起落落。心中有万分的感慨&#xff0c;总结下来有这几点分享给大家&#xff0c;在选择培训机构时能看清本质&#xff0c;找到适合自己靠谱的机构学Java…

Go大道至简之抓取网页

目录前期准备环境教程浏览器启动命令启动Rod启动浏览器Rod自动查找浏览器路径并启动输入和点击、Enter动作多页面抓取前期准备 环境 Go版本大于等于1.18Go模块源更换&#xff0c;加速模块下载go env -w GO111MODULEon go env -w GOPROXYhttps://goproxy.cn,directRod模块 Rod…

4年经验来面试20K的测试岗,连基础都不会,还不如招应届生。

公司前段时间缺人&#xff0c;也面了不少测试&#xff0c;结果竟然没有一个合适的。一开始瞄准的就是中级的水准&#xff0c;也没指望来大牛&#xff0c;提供的薪资在10-20k&#xff0c;面试的人很多&#xff0c;但平均水平很让人失望。 看简历很多都是3、4年工作经验&#xf…

chatGPT做了这么一道数学题,我陷入了沉思

已知 2cos23cosasina−3sin2a1,并且a∈(−32π,−π)2cos^{2}3cosasina-3sin^{2}a1 ,并且a\in(-\frac{3}{2}\pi,-\pi) 2cos23cosasina−3sin2a1,并且a∈(−23​π,−π) 求 2sin(π−a)−3sin(π2a))4sina−9cosa\frac{2sin(\pi-a)-3sin(\frac{\pi}{2}a))}{4sina-9cosa} 4sina−…

Sage X3 ERP的称重插件帮助食品和化工企业实现精细化管理

目录 需要称重插件管理的行业客户 Sage X3 ERP称重插件管理的两个关键单位 Sage X3 ERP称重插件的特色 Sage X3 ERP称重插件管理的重要性 需要称重插件管理的行业客户 术语“实际重量”表示在销售和运输时捕获的物品重量。生产销售家禽、肥料、钢材或任何其他需要跟踪实…

【Spark分布式内存计算框架——Spark SQL】4. DataFrame(上)

3.1 DataFrame是什么 在Spark中&#xff0c;DataFrame是一种以RDD为基础的分布式数据集&#xff0c;类似于传统数据库中的二维表格。DataFrame与RDD的主要区别在于&#xff0c;前者带有schema元信息&#xff0c;即DataFrame所表示的二维表数据集的每一列都带有名称和类型。 使…

chatGPT 配合excel /maxscript使用_初试

EXCEL 配合chatGPT方法一&#xff1a;利用excel的開發工具1打開excel的VB编辑器&#xff1a;如果頂部菜單上沒有看到開發工具&#xff0c;需要先按下面步驟打開開發工具&#xff1a;這樣按上面步驟就可以打開excel的開發工具~ 然後點擊VB~ 2让chatGPT帮忙写脚本在chatGPT上提问…

Tomcat是如何隔离Web应用的

Tomcat通过自定义的类加载器WebAppClassLoader打破了双亲委托机制&#xff0c;目的就是为了优化加载Web应用目录下的类。Tomcat 作为 Servlet 容器&#xff0c;它负责加载我们Servlet 类&#xff0c;此外它还负责加载 Servlet 所依赖的 JAR 包。并且Tomcat 本身也是也是一个 Ja…

petalinux 2020.2 离线编译

链接&#xff1a;[https://www.xilinx.com/support/download/index.html/content/xilinx/en/downloadNav/embedded-design-tools.html] 2、在ubuntu下安装必要运行库。 1、sudo apt-get install iproute2 gawk python3 python 2、sudo apt-get install build-essential gcc gi…

第七届蓝桥杯省赛——8冰雹数(递归)

题目&#xff1a;任意给定一个正整数N&#xff0c;如果是偶数&#xff0c;执行&#xff1a; N / 2如果是奇数&#xff0c;执行&#xff1a; N * 3 1生成的新的数字再执行同样的动作&#xff0c;循环往复。通过观察发现&#xff0c;这个数字会一会儿上升到很高&#xff0c;一会…

海外问卷调查怎么做?手把手教会你如何薅老外的羊毛

问卷调查相信大家都不陌生。许多组织在推出新项目或新产品之前&#xff0c;会对全社会进行问卷调查&#xff0c;调查消费者或受众对产品的期望和价格的接受范围。东哥今天给大家介绍的就是海外问卷调查项目&#xff0c;外国人的羊毛&#xff0c;带你们薅定了&#xff01;参与海…

基于ArgoCD实现k8s环境下的持续部署

什么是 argo CD Argo CD is a declarative, GitOps continuous delivery tool for Kubernetes. Argo CD是一个基于Kubernetes的声明式的GitOps工具。 这里我们引入了一个新的概念&#xff0c; 什么是GitOps GitOps是以Git为基础&#xff0c;使用CI/CD来更新运行在云原生环境…

电脑资料如何转移到新电脑?教你3种数据迁移技巧

当下&#xff0c;电脑越来越普及&#xff0c;更换频率也越来越高。当我们购买新电脑&#xff0c;需要将旧电脑上的文件资料迁移到新电脑上&#xff0c;方便使用&#xff0c;电脑资料如何转移到新电脑&#xff1f;其实我们完全可以自己解决哦&#xff0c;下面一起来看下电脑资料…

VMware 修复了三个身份认证绕过漏洞

Bleeping Computer 网站披露&#xff0c;VMware 近期发布了安全更新&#xff0c;以解决 Workspace ONE Assist 解决方案中的三个严重漏洞&#xff0c;分别追踪为 CVE-2022-31685&#xff08;认证绕过&#xff09;、CVE-2022-31686 &#xff08;认证方法失败&#xff09;和 CVE-…

python应用之小麦生育期气象因子计算——基于pandas库

背景 本次介绍一下python的pandas包操作Excel&#xff08;或者CSV等&#xff09;&#xff0c;应用情景是计算不同站点小麦多年生育期内的气象因子的特征&#xff08;积温、降雨、辐射等&#xff09; 主要涉及以下知识点&#xff1a; 儒略日转换数据框值获取与字符串加法基于que…

.md文件转.pdf文件

一、安装VS code vscode是一个轻量级的、可扩展性十分强的开发编辑器。过程略&#xff0c;比较简单。 二、安装插件Markdown PDF 直接 install 就可以了。 我这里出现了安装失败的情景&#xff0c;这时候可以通过它给的提示&#xff0c;安转markdown-pdf 的 .vsix 文件&#…