当前位置: 首页> 教育> 培训 > 【Elegant Programming (优雅的编程)】如何用合理的封装优雅的化解三层以上的 if-else ?

【Elegant Programming (优雅的编程)】如何用合理的封装优雅的化解三层以上的 if-else ?

时间:2025/7/13 3:47:26来源:https://blog.csdn.net/qq_37967783/article/details/140906085 浏览次数:0次

在这里插入图片描述

👉博主介绍: 博主从事应用安全和大数据领域,有8年研发经验,5年面试官经验,Java技术专家,WEB架构师,阿里云专家博主,华为云云享专家,51CTO 专家博主

⛪️ 个人社区:个人社区
💞 个人主页:个人主页
🙉 专栏地址: ✅ Java 中级
🙉八股文专题:剑指大厂,手撕 Java 八股文

文章目录

      • 1. 写下前面
      • 2. 如何用合理的封装优雅的化解三层以上的 if-else ?
      • 3. 写在最后

1. 写下前面

今天跟大家分享一个 Githup 的项目,这个项目叫:Elegant Programming (优雅的编程),这个项目目前在持续更新中。
Elegant Programming (优雅的编程) 的 Githup 链接:https://github.com/pydlove/ElegantProgramming?tab=readme-ov-file

Elegant Programming 是分享如何将代码写的更加优雅,代码不仅是程序运行的,更是人读的。既然是人读的,那么我就应该让它可读性更强一点。这个项目中所有的案例都是我平时工作中的积累,也没有刻意想要系统化的整理这种编程技巧,也是想到点就写一点。但是我保证你一定能有所收获。

今天我们分享 Elegant Programming 中的一个案例:如何用合理的封装优雅的化解三层以上的 if-else ?

接下来我们直接进入正文。

2. 如何用合理的封装优雅的化解三层以上的 if-else ?

首先看需求介绍:

package com.pany.camp.example.case6;import com.pany.camp.example.case4.main.ExampleHandler;
import com.pany.camp.example.case4.main.GraceExampleHandler;/**** @description:  ParamExample* @copyright: @copyright (c) 2022* @company: aiocloud* @author: panyong* @version: 1.0.0* @createTime: 2024-07-29 21:39*/
public class ThreeNestedIfElseExample {public static void main(String[] args) {// 主题:如何用合理的封装优雅的化解三层以上的 if-else ?//// 首先我先说下需求:这一次我们需要做一个心跳检测的服务,大致步骤如下:// 1、是否开启心跳检测?// 2、从 redis 上获取搜索的节点,然后对获取的结果进行判断// 3、遍历所有节点,针对每个节点做心跳检测// 4、心跳检测分为两个检测方式:主观检测 + 客观检测//// 基于这个需求,分别看下面两种实现,在代码我有明确指明哪些层是可以使用封装来减少 if-else 嵌套的层数,// 并且通过封装让代码可读性更强。// 错误案例 ExampleHandler().handle()// 正确案例 GraceExampleHandler().handle()new ExampleHandler().handle();new GraceExampleHandler().handle();}
}

然后我们先看错误案例,这个错误案例也是我在这么多年工作中经常见到的,很多写了三五年代码的,也可能会这样写;

package com.pany.camp.example.case6.main;import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.pany.camp.common.redis.RedisKey;
import com.pany.camp.common.redis.RedisNameSpace;
import com.pany.camp.common.redis.RedisOperate;
import lombok.extern.slf4j.Slf4j;import java.util.List;
import java.util.Objects;/**** @description:  ExampleHandler* @copyright: @copyright (c) 2022 * @company: aiocloud* @author: panyong* @version: 1.0.0 * @createTime: 2024-08-03 16:56*/
@Slf4j
public class ExampleHandler {private static final long HEARTBEAT_TIMEOUT = 1000 * 60 * 5;public void handle() {// 假设我们这里要做心跳检测服务if (isOpenHeartbeatCheck()) {// 首先获取所有节点Object hostObj = RedisOperate.get(new RedisKey(RedisNameSpace.SYSTEM_HEARTBEAT_HOST));if (Objects.isNull(hostObj)) {log.error("system heartbeat host not existed, please check in redis");return;}// 遍历节点检查心跳List<String> hostNames = JSONObject.parseObject(hostObj.toString(), new TypeReference<List<String>>() {});for (String hostName : hostNames) {// 主观检查:如果没有查看到注册心跳,证明可能下线了Object hostTimeObj = RedisOperate.get(new RedisKey(RedisNameSpace.SYSTEM_HEARTBEAT_TIME, hostName));if (Objects.isNull(hostTimeObj)) {log.error("system heartbeat time, host: {} not report time for redis", hostName);// 客观判断:如果心跳超时了,那么我们在请求下节点的接口,根据接口是否响应,来判断节点是否还存活if (!requestNodeAlive(hostName)) {// 确认节点下线了,做一些善后的处理,如:故障转移,通知其他节点,通知用户等AftermathHandler.handle(hostName);}} else {// 主观检查:首先基于时间戳判断,是否上报的心跳超时了long hostTime = Long.parseLong(hostTimeObj.toString());if (System.currentTimeMillis() - hostTime > HEARTBEAT_TIMEOUT) {// 客观判断:如果心跳超时了,那么我们在请求下节点的接口,根据接口是否响应,来判断节点是否还存活if (!requestNodeAlive(hostName)) {// 确认节点下线了,做一些善后的处理,如:故障转移,通知其他节点,通知用户等AftermathHandler.handle(hostName);}}}}}}private boolean requestNodeAlive(String hostName) {return httpRequestByHostName(hostName);}private boolean httpRequestByHostName(String hostName) {// 假设这里是通过 http 请求来判断节点是否还存活return false;}private boolean isOpenHeartbeatCheck() {// 假设这里是从环境配置中读取是否开启心跳检测return getFromApplicationConfig();}private Boolean getFromApplicationConfig() {return true;}
}

阅读完错误的案例,接下来看正确的案例,如何用封装简化逻辑?

package com.pany.camp.example.case6.main;import com.alibaba.fastjson2.JSONObject;
import com.alibaba.fastjson2.TypeReference;
import com.pany.camp.common.redis.RedisKey;
import com.pany.camp.common.redis.RedisNameSpace;
import com.pany.camp.common.redis.RedisOperate;
import lombok.extern.slf4j.Slf4j;import java.util.List;
import java.util.Objects;/**** @description:  GraceExampleHandler* @copyright: @copyright (c) 2022 * @company: aiocloud* @author: panyong* @version: 1.0.0 * @createTime: 2024-08-03 16:56*/
@Slf4j
public class GraceExampleHandler {private static final long HEARTBEAT_TIMEOUT = 1000 * 60 * 5;public void handle() {// 假设我们这里要做心跳检测服务if (isOpenHeartbeatCheck()) {// (这里使用封装)如果开启心跳检测,那么我们开始心跳检测的处理doHeartbeatCheck();}}private void doHeartbeatCheck() {// 首先获取所有节点Object hostObj = RedisOperate.get(new RedisKey(RedisNameSpace.SYSTEM_HEARTBEAT_HOST));if (Objects.isNull(hostObj)) {log.error("system heartbeat host not existed, please check in redis");return;}// 遍历节点检查心跳List<String> hostNames = JSONObject.parseObject(hostObj.toString(), new TypeReference<List<String>>() {});for (String hostName : hostNames) {// (这里使用封装)针对选中的或者单个的主机节点进行心跳检测if (checkIsOffline(hostName)) {// (这里使用封装)确认节点下线了,做一些善后的处理,如:故障转移,通知其他节点,通知用户等AftermathHandler.handle(hostName);}}}private boolean checkIsOffline(String hostName) {// 主观检查:首先基于时间戳判断,是否上报的心跳超时了Object hostTimeObj = RedisOperate.get(new RedisKey(RedisNameSpace.SYSTEM_HEARTBEAT_TIME, hostName));if (Objects.isNull(hostTimeObj)) {log.error("system heartbeat time, host: {} not report time for redis", hostName);return true;}long hostTime = Long.parseLong(hostTimeObj.toString());// 主观检查:首先基于时间戳判断,是否上报的心跳超时了 +  客观判断:如果心跳超时了,那么我们在请求下节点的接口,根据接口是否响应,来判断节点是否还存活if ((System.currentTimeMillis() - hostTime > HEARTBEAT_TIMEOUT) && requestNodeAlive(hostName))  {return true;}return false;}private boolean requestNodeAlive(String hostName) {return httpRequestByHostName(hostName);}private boolean httpRequestByHostName(String hostName) {// 假设这里是通过 http 请求来判断节点是否还存活return false;}private boolean isOpenHeartbeatCheck() {// 假设这里是从环境配置中读取是否开启心跳检测return getFromApplicationConfig();}private Boolean getFromApplicationConfig() {return true;}
}

3. 写在最后

在工作中,我会因为多了一个空格和一个换行而去修改。工作中大家写代码还是要有一定追求的,我觉得不应该只是为了完成这个任务,获取的能力提升还是自己的。

然后更多的编程技巧可以去 Githup上看这个开源项目。
链接:https://github.com/pydlove/ElegantProgramming?tab=readme-ov-file

精彩专栏推荐订阅:在下方专栏👇🏻
✅ 2023年华为OD机试真题(A卷&B卷)+ 面试指导
✅ 精选100套 Java 项目案例
✅ 面试需要避开的坑(活动)
✅ 你找不到的核心代码
✅ 带你手撕 Spring
✅ Java 初阶

在这里插入图片描述

关键字:【Elegant Programming (优雅的编程)】如何用合理的封装优雅的化解三层以上的 if-else ?

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

责任编辑: