首页 > 编程知识 正文

java代码块嵌套不超过几层,javawhile内嵌套if

时间:2023-05-05 04:07:20 阅读:173351 作者:589

在Java中,多层嵌套的if-else代码的重构1 .背景我想你已经看到过这样的代码。

if(true )//dosomethingif(true )//dosomethingif ) true )//dosomethingif )//dosomethingif ) /

结论首先,重构这种嵌套if-else的代码主要采用了以下三种方法:

1. 三目运算符

2. 方法分层

3. 多态

2 .优化思路通过实例展示了这一重构过程。 重构前的商业代码是这样的。

2.1.三目运算符

用三目算子优化一些简单的if-else。

是这样的:

不使用三目运算符:

查询参数. getcreatestarttime (!=0) stringstrstartdate=dateutils.long to format date (query param.getcreatestarttime () ); } 使用三目运算符:

String strStartDate=! (query param.getcreatestarttime (==0||query param.getcreateendtime )==0)? dateutils.long to format date (query param.getcreatestarttime ) ) : null;2.2.方法分层

所谓方法分层,是受设计模式中单一责任原则(SRP )的启发,需要清空代码中的许多参数。 此时,抽象一个方法进行所有参数的合法性检查,以实现代码的简化。 业务代码只进行业务逻辑编制,参数校验统一采用参数校验方法进行。

是这样的:

@ overridepublicvoidchecklistqueryparams (listqueryparam ) if ) objects.isnull ) queryparam.getpageno ) | objects.is null (query param.getpagesize () ) thrownewchartexception ) msgcode.constraint_violation,page_paration }

checkparamsservice.checklistqueryparams;2.3.多态

这两种方法都是对if-else代码结构的局部优化,为了从整体上减少业务代码中的嵌套if-else,考虑利用多态性的特性,对每个业务分别处理,不通过接口进行业务判断。 抽象业务代码(这里即是指条件查询方法),作为基类,为每个业务实现子类。

具体例子如下。

BackgroundConditionQuery.java

publicabstractclassbackgroundconditionqueryt { publicabstractlisttdoquery (listqueryparam,conditionquerypararamscond

publicclassbackgroundchartlistconditionqueryextendsbackgroundconditionquery { @ autowiredprivatechartdaochartdao; @ overridepubliclistchartdoquery (listqueryparamqueryparam,ConditionQueryParams conditionQ

ueryParams) { List<Chart> chartList = new ArrayList<>(); if (!Objects.isNull(queryParam.getSceneStatus())) { if (queryParam.getSceneStatus().equals(CHECK_STATUS_ALL)) { chartList = queryWithoutSceneStatus(conditionQueryParams); } else { byte sceneStatus = queryParam.getSceneStatus(); chartList = chartDao.selectByConditionWithSceneStatus(conditionQueryParams.getStrStartDate() , conditionQueryParams.getStrEndDate(), conditionQueryParams.getId() , conditionQueryParams.getChartName(), conditionQueryParams.getCreatorId(), sceneStatus); } } else { chartList = queryWithoutSceneStatus(conditionQueryParams); } return chartList; } private List<Chart> queryWithoutSceneStatus(ConditionQueryParams conditionQueryParams) { return chartDao.selectByConditionWithAll(conditionQueryParams.getStrStartDate() , conditionQueryParams.getStrEndDate(), conditionQueryParams.getId() , conditionQueryParams.getChartName(), conditionQueryParams.getCreatorId()); }}

BackgroundTemplateListConditionQuery.java

public class BackgroundTemplateListConditionQuery extends BackgroundConditionQuery { @Autowired private TemplateDao templateDao; @Override public List<Template> doQuery(ListQueryParam queryParam, ConditionQueryParams conditionQueryParams) { List<Template> templateList = new ArrayList<>(); if (!Objects.isNull(queryParam.getApproveStatus())) { if (queryParam.getApproveStatus().equals(CHECK_STATUS_ALL)) { templateList = queryWithoutApproveStatus(conditionQueryParams); } else { byte approveStatus = queryParam.getSceneStatus(); templateList = templateDao.selectByConditionWithApproveStatus(conditionQueryParams.getStrStartDate() , conditionQueryParams.getStrEndDate(), conditionQueryParams.getId() , conditionQueryParams.getChartName(), conditionQueryParams.getCreatorId(), approveStatus); } } else { templateList = queryWithoutApproveStatus(conditionQueryParams); } return templateList; } private List<Template> queryWithoutApproveStatus(ConditionQueryParams conditionQueryParams) { return templateDao.selectByConditionWithAll(conditionQueryParams.getStrStartDate() , conditionQueryParams.getStrEndDate(), conditionQueryParams.getId() , conditionQueryParams.getChartName(), conditionQueryParams.getCreatorId()); }}

这样之后,业务接口代码就只需要进行调用工作,完成了大量的嵌套if-else代码的重构。最后,业务接口代码就像这样:

List<Chart> chartList = new ArrayList<>(); // 时间日期筛选 String strStartDate = !(queryParam.getCreateStartTime() == 0 || queryParam.getCreateEndTime() == 0) ? DateUtils.longToFormatDate(queryParam.getCreateStartTime()) : null; String strEndDate = !(queryParam.getCreateStartTime() == 0 || queryParam.getCreateEndTime() == 0) ? DateUtils.longToFormatDate(queryParam.getCreateEndTime()) : null; // 其他筛选条件 String id = StringUtils.equals(SEARCH_TYPE_TEMPLATE_Id, queryParam.getSearchType()) ? queryParam.getSearchValue() : null; String chartName = StringUtils.equals(SEARCH_TYPE_TEMPLATE_NAME, queryParam.getSearchType()) ? queryParam.getSearchValue() : null; String creatorId = StringUtils.equals(SEARCH_TYPE_CREATOR_Id, queryParam.getSearchType()) ? queryParam.getSearchValue() : null; ConditionQueryParams conditionQueryParams = new ConditionQueryParams(strStartDate, strEndDate, id, chartName, creatorId); chartList = backgroundChartListConditionQuery.doQuery(queryParam, conditionQueryParams);

2.4.其他方法
除了以上方法外,还有两种方法可以进行嵌套if-else代码的重构,比如用一些特殊的数据结构去或者设计模型思想进行,如:
1.使用Map替代分支语句,把所有状态类型预先缓存在Map里,需要调用的时候直接get获取具体状态类型,以此消除分支;
2.使用卫语句,优化代码顺序,减少else条件的使用;
3.设计模式中策略模式和状态模式,也可以用于减少业务接口的嵌套if-else代码,但归根到底还是用到了多态的特性去进行抽象。

3.反思

重构前的代码,也是能跑通的,并且思路也是清晰的,但是为什么还要花力气去重构他呢?这个问题这就是重构需要解决的问题之一。重构前的代码在当前需求下是能够胜任工作的,但是一个月后,或者一年之后,甚至三五年后,这份代码就会因为历任产品的不同需求无限膨胀,一点也不”开发-闭合“,并且维护难度系数和if-else嵌套层数呈指数型增长,最终收敛于某次线上重大事故。重构后的代码就会减少这样情况的发生。因此写下这篇博客,一是对此次重构过程复盘,二是提炼此类问题的重构模型,方便以后查阅补充。

版权声明:该文观点仅代表作者本人。处理文章:请发送邮件至 三1五14八八95#扣扣.com 举报,一经查实,本站将立刻删除。