【设计模式实战】用三种设计模式去优化if-else屎山代码!!!

优化前提

  • 【设计模式】之策略模式
  • 【设计模式】之工厂模式(三种)
  • 【设计模式】之模板方法模式

前言

我们之前也学习了不少设计模式,今天给大家介绍一个案例,帮助大家更加熟悉设计模式,并能够在自己写项目的时候能够下意识的使用设计模式,避免写出屎山代码。🌈

提示:不清楚策略、工厂、模板方法模式的小伙伴可以参考上方文章。


一、 抛出屎山代码

我就以一个简单的代码模拟下业务,像我们平时写项目的时候,这种if-else语句非常常见,比如说:在判断支付类型的时候,在参数校验的时候等等。过多的if-else,会使代码冗余、可读性不好,最重要的是违反了“开闭原则”,拓展性非常的差,后面的同事看了后会非常的痛苦,内心一顿臭骂,为了避免被后面的同事吐槽谩骂,我们要写出更加优雅的代码。

void Example1(){String name = "小杰";if (name.equals("刘二")){System.out.println("刘二完成任务");} else if (name.equals("张三")) {System.out.println("张三完成任务");} else if (name.equals("李四")) {System.out.println("李四完成任务");} else if (name.equals("王五")) {System.out.println("王五完成任务");} else if (name.equals("赵六")) {System.out.println("赵六完成任务");} else if (name.equals("苏七")) {System.out.println("苏七完成任务");}}

二、如何解决

我们一步步引入设计模式,帮助大家理解

1.使用策略模式

分析代码

我们可以将if里面执行的代码可以看作一个个不同的策略,这样我们就可以引入策略模式去优化下面代码。

优化代码

首先,我们定义一个策略接口。

public interface Handler extends InitializingBean {void show();
}

实现具体的策略

public class LiSi implements Handler{//执行相应的策略@Overridepublic void show() {System.out.println("李四完成了任务");}//这个方法是策略类初始化后需要执行的逻辑,这个我们先不管@Overridepublic void afterPropertiesSet() throws Exception {Factory.register("李四",this);}
}......

优化后代码

void OnlyStrategy(){String name = "小杰";if (name.equals("刘二")){new LiuEr().show();} else if (name.equals("张三")) {new ZhangSan().show();} else if (name.equals("李四")) {new LiSi().show();} else if (name.equals("王五")) {new WangWu().show();} else if (name.equals("赵六")) {new ZhaoLiu().show();} else if (name.equals("苏七")) {new SuQi().show();}}

2.引入工厂模式

分析代码

虽然我们引入了策略模式,但是仍然未解决if-else语句,并且每次使用策略都必须先new出来,后续拓展仍然需要添加if-else代码,这样看起来代码更加复杂了,性能更差了。别急,我们继续添加工厂模式,继续优化代码。

优化代码

我们定义一个工厂,让工厂帮我们去生产对应的对象。

public class Factory {//我们将策略类存入HashMap里面private static Map<String, Handler> map = new HashMap<>();//根据name获取对应的策略类public static Handler getInvokeStrategy(String name){return map.get(name);}//将策略类放入map里面public static void register(String name,Handler handler){if (StringUtils.isEmpty(name) || null == handler){return;}map.put(name,handler);}
}

这里给大家解释afterPropertiesSet()方法里面的逻辑

public class LiSi implements Handler{@Overridepublic void show() {System.out.println("李四完成了任务");}@Overridepublic void afterPropertiesSet() throws Exception {//策略类初始化后,自动将策略类注册到HashMap里面Factory.register("李四",this);}
}

优化后代码

//我们成功的干掉了if-else
void haveFactory(){String name = "张三";Handler handler = Factory.getInvokeStrategy(name);handler.show();}

3.引入模板方法模式

分析代码

到这里虽然我们成功的干掉了if-else语句,但是又引出了一个问题,

 String name = "小杰";if (name.equals("刘二")){System.out.println("刘二完成任务");} else if (name.equals("张三")) {System.out.println("张三完成任务");} else if (name.equals("李四")) {System.out.println("李四完成任务");} else if (name.equals("王五")) {return "王五完成了任务";} else if (name.equals("赵六")) {return "赵六完成任务";} else if (name.equals("苏七")) {return "苏七完成任务";}

我们可以看到,五五、赵六、苏七策略跟其他语句的策略并不一样。

解决思路:

  1.  在策略接口添加不同的策略(不使用)
  2. 使用模板方法模式,每个策略类实现自己对应的策略(推荐使用)

给大家解释下为什么不使用第一种,如果我们在策略接口添加不同的策略,我们的策略类就必须要实现所以的策略,但是策略类并不需要实现所有的策略,它只需要实现自己的那一个策略,所以这个思路不可行。

优化代码

我们将策略接口改为策略抽象类

public abstract class AbstractHandler implements InitializingBean {//策略1public void show(String name){ throw new UnsupportedOperationException();}//策略2public String eat(String name){ throw new UnsupportedOperationException();}
}

当然,我们的工厂和策略类也要修改,张三策略类和王五策略类实现不同的策略。


//策略工厂
public class Factory2 {//将Handler改为AbstractHandlerprivate static Map<String, AbstractHandler> map = new HashMap<>();public static AbstractHandler getInvokeStrategy(String name){return map.get(name);}public static void register(String name,AbstractHandler handler){if (StringUtils.isEmpty(name) || null == handler){return;}map.put(name,handler);}
}
//张三策略类
@Component
public class WangWu extends AbstractHandler {@Overridepublic String eat(String name) {return "王五吃东西";}@Overridepublic void afterPropertiesSet() throws Exception {Factory2.register("王五",this);}
}
//王五策略
@Component
public class ZhangSan extends AbstractHandler {@Overridepublic void show(String name) {System.out.println("张三完成了任务");}@Overridepublic void afterPropertiesSet() throws Exception {Factory2.register("张三",this);}
}
......

优化后代码

 @Testvoid haveTemplate(){String name1 = "王五";AbstractHandler handler1 = Factory2.getInvokeStrategy(name1);System.out.println(handler1.eat(name1));String name2 = "张三";AbstractHandler handler2 = Factory2.getInvokeStrategy(name2);handler2.show(name2);}

随着通过我们一步步的添加设计模式,使我们的代码更加简洁,也符合了“开闭原则”,到这里,我们就优化完成了。


总结

        虽然设计模式帮助我们优化了代码,是代码更加的规范,但是,切不可为了使用设计模式而去使用设计模式,在某种业务场景使用if-else语句可能比设计模式更加适合,所以大家要结合业务场景,选出最优的解决方法。

今天的分享就到这里,喜欢的小伙伴可以一键三连哦,我们下期再见。✋✋✋

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

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

相关文章

PXE远程部署CentOS系统

文章目录 在局域网内搭建PXE服务器PXE 启动组件PXE的优点实验一、搭建PXE服务器&#xff0c;实现远程部署CentOS系统环境准备server关闭防火墙安装组件准备 Linux 内核、初始化镜像文件及PXE引导文件配置启用TFTP 服务配置启动DHCP服务准备CentOS 7 安装源配置启动菜单文件 Cli…

centos7.9系统rabbitmq3.8.5升级为3.8.35版本

说明 本文仅适用rabbitmq为RPM安装方式。 升级准备 查看环境当前版本&#xff1a; # cat /etc/redhat-release CentOS Linux release 7.9.2009 (Core) # rabbitmqctl status Status of node rabbitmq01 ... RuntimeOS PID: 19333 OS: Linux Uptime (seconds): 58 Is under …

解决本地启动项目,用IP地址访问失败问题

解决方法&#xff1a;看看index.html页面有没有 这个标签&#xff0c;将它注释掉

Go 语言基础之指针、复合类型【数组、切片、指针、map、struct】

1、数组 特别需要注意的是&#xff1a;在 Go 语言中&#xff0c;数组长度也是数组类型的一部分&#xff01;所以尽管元素类型相同但是长度不同的两个数组&#xff0c;它们的类型并不相同。 1.1、数组的初始化 1.1.1、通过初始化列表{}来设置值 var arr [3]int // int类型的数…

获取波形极值与间距并显示

获取并显示波形的极值与极值间距 1、流程 1、通过signal.find_peaks获取极大值 2、获取极大值下标 3、获取极大值对应的值 4、获取极大值的下标间距(就是隔多远有一个极大值) 5、获取极大值间距的标准差、方差、均值、最大值 6、图形展示波形图并标记极大值2、效果图 3、示…

专项技能训练五《云计算网络技术与应用》实训8-1:建立基于OpenvSwitch的GRE隧道

文章目录 建立基于OpenvSwitch的GRE隧道1. 使用VMware安装2个CentOS 7虚拟机&#xff0c;安装时记得都开启CPU虚拟化&#xff0c;第一台命名为“Docker”&#xff0c;第二台命名为“KVM”。2. 安装完虚拟机后&#xff0c;进入虚拟机&#xff0c;修改网络配置&#xff08;onboot…

软件架构的艺术:探索演化之路上的18大黄金原则

实际工作表明&#xff0c;一步到位的设计往往不切实际&#xff0c;而演化原则指导我们逐步优化架构&#xff0c;以灵活响应业务和技术的变化。这不仅降低了技术债务和重构风险&#xff0c;还确保了软件的稳定性和可扩展性。同时&#xff0c;架构的持续演进促进了团队协作&#…

新华三VRRP配置

新华三VRRP配置 配置步骤 (1).基础配置&#xff1a; CORE1&#xff1a; [CORE1]vlan 10 //创建vlan10 [CORE1-vlan10]int vlan 10 //进入vlanif 10 [CORE1-Vlan-interface10]ip add 192.168.10.1 24 //配置ip [CORE1-Vlan-interface10]int g1/0/2 //进入接口 [C…

常见错误以及如何纠正它们

团队和关键结果目标 (OKR) 之间的关系是深刻且至关重要的。总而言之&#xff0c;一切都应该是相互关联的。正如《团队的智慧》一书中所强调的&#xff1a; 在团队中&#xff0c;没有什么比每个成员对共同目标和一组相关绩效目标的承诺更重要的了&#xff0c;而团队对此负有共同…

通过管理系统进行升级怎么选?

现在通过系统来做办公效率提升的又很多&#xff0c;但怎么选&#xff0c;确实很关键。 我们是在去年年初的时候进行企业系统化的。当时刚摘下口罩&#xff0c;领导也是意识到团队办公的不便&#xff0c;数据管理的混乱&#xff0c;业务流转的低效等原因&#xff0c;开始寻找各…

CUDA、CUDNN、Pytorch三者之间的关系

这个东西嘛&#xff0c;我一开始真的是一头雾水&#xff0c;安装起来真是麻烦死了。但是随着要复现的项目越来越多&#xff0c;我也不得不去学会他们是什么&#xff0c;以及他们之间的关系。 首先&#xff0c;一台电脑里面允许有多种版本的cuda存在&#xff0c;然后cuda分为run…

大数据API技术分享:使用API接口采集淘宝数据(商品详情丨关键词搜索丨店铺所有商品)

使用API接口采集淘宝数据&#xff08;商品详情、关键词搜索、店铺所有商品&#xff09;是大数据领域常见的应用场景。以下是一些关于如何使用API接口进行这些操作的技术分享&#xff1a; 1. 获取API权限 首先&#xff0c;你需要在淘宝开放平台注册成为开发者&#xff0c;并创建…

从简单逻辑到复杂计算:感知机的进化与其在现代深度学习和人工智能中的应用(下)

文章目录 第一章&#xff1a;感知机的局限性1.1 异或门的挑战1.2 线性与非线性问题 第二章&#xff1a;多层感知机2.1 已有门电路的组合2.2 实现异或门 第三章&#xff1a;从与非门到计算机 文章文上下两节 从简单逻辑到复杂计算&#xff1a;感知机的进化与其在现代深度学习和人…

DigitalOcean 应用托管平台级更新:应用端到端运行时性能大幅改进

DigitalOcean 希望可以为企业提供所需的工具和基础设施&#xff0c;以帮助企业客户加速云端的开发&#xff0c;实现业务的指数级增长。为此 DigitalOcean 在 2020 年就推出了App Platform。 App Platform&#xff08;应用托管&#xff09; 是一个完全托管的 PaaS 解决方案&…

代码随想录Day 40|Leetcode|Python|139.单词拆分 ● 关于多重背包,你该了解这些! ● 背包问题总结篇!

139.单词拆分 给你一个字符串 s 和一个字符串列表 wordDict 作为字典。如果可以利用字典中出现的一个或多个单词拼接出 s 则返回 true。 注意&#xff1a;不要求字典中出现的单词全部都使用&#xff0c;并且字典中的单词可以重复使用。 解题思路&#xff1a; 确定dp数组含义…

火山引擎数据飞轮携手美宜佳 探索拓店营销新思路

在刚刚过去的 3 月&#xff0c;美宜佳又交出了门店增长的高分答卷。 最新数据显示&#xff0c;美宜佳在全国的连锁店数已经超过 35000 家&#xff0c;每年净增 3000-4000 家店&#xff0c;月均服务顾客超 2 亿人次&#xff1b;同时&#xff0c;在中国连锁经营协会(CCFA)近日发布…

有哪些方式可以有效地评估精益生产咨询公司的能力?

在寻求精益生产咨询服务的过程中&#xff0c;评估咨询公司的能力至关重要。这不仅关乎企业精益生产转型的成功与否&#xff0c;更直接影响到企业未来的竞争力和发展。那么&#xff0c;有哪些方式可以有效地评估精益生产咨询公司的能力呢&#xff1f; 首先&#xff0c;了解咨询公…

Linux网络-PXE高效批量网络装机(命令+截图详细版)

目录 一.部署PXE远程安装服务 1.PXE概述 1.1.PXE批量部署的优点 1.2.要搭建PXE网络体系的前提条件 2.搭建PXE远程安装服务器 2.1.修改相关网络配置&#xff08;仅主机模式&#xff09; 2.2.关闭防火墙&#xff08;老规矩&#xff09; 2.3.保证挂载上 2.4.准备好配置文…

语音识别--声音位置与起始位置检测

⚠申明&#xff1a; 未经许可&#xff0c;禁止以任何形式转载&#xff0c;若要引用&#xff0c;请标注链接地址。 全文共计3077字&#xff0c;阅读大概需要3分钟 &#x1f308;更多学习内容&#xff0c; 欢迎&#x1f44f;关注&#x1f440;【文末】我的个人微信公众号&#xf…

代码随想录最后一天!

这是长达63天的最后一天一年的六分之一&#xff0c;我跟着卡哥完成了代码随想录的所有打卡。每天都写下了一篇关于自己做题的小博客。其中有的写的精细&#xff0c;有的潦草&#xff0c;但是都是我一路走来的脚步。 虽然有的题目还是不太理解&#xff0c;但是我依旧自信昂首&am…