Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/337.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 降低代码的复杂性_Java_Refactoring_Anti Patterns - Fatal编程技术网

Java 降低代码的复杂性

Java 降低代码的复杂性,java,refactoring,anti-patterns,Java,Refactoring,Anti Patterns,我现在被一些非常奇怪的类卡住了,它们的逻辑混淆了。以下是生成数据库查询的代码示例: if(realTraffic.getPvkp() != null) { //Admission point if(BeanUtils.isGuidEntity(realTraffic.getPvkp())) { findParameters += " and (" + staticTableName() + ".guidPvkp = '" + realTraffic.ge

我现在被一些非常奇怪的类卡住了,它们的逻辑混淆了。以下是生成数据库查询的代码示例:

if(realTraffic.getPvkp() != null) {
   //Admission point
   if(BeanUtils.isGuidEntity(realTraffic.getPvkp())) {
      findParameters +=
         " and (" + staticTableName() + ".guidPvkp = '" + realTraffic.getPvkp().getGuid()
         + "' or (" + staticTableName() + ".guidPvkpOut = '" + realTraffic.getPvkp().getGuid()
         + "' and " + staticTableName() + ".requestType = " + RequestBean.TRANSIT_TYPE
         + ")";
      if (companyType == CompanyBean.PP_TYPE && !realTraffic.isSkipOther()) {
         // TODO - add non-formed
         findParameters += " or (" + staticTableName() + ".guidPvkpOut is null "
         + " and " + staticTableName() + ".requestType = " + RequestBean.TRANSIT_TYPE
         + ")";
      }
      findParameters += ") ";
   } else {
     // Territorial department
      if(BeanUtils.isGuidEntity(realTraffic.getPvkp().getTerritorialDepartment())) {
         findParameters +=
            " and (Pvkp.guidTerritorialDepartment = '" + realTraffic.getPvkp().getTerritorialDepartment().getGuid()
            + "' or Pvkp.guidFtsDepartment = '" + realTraffic.getPvkp().getTerritorialDepartment().getGuid()
            + "' ) ";
      }
   }
}
这只是我在方法中进行的大量复杂检查的一部分。问题是——如何处理这样的代码——它有很多嵌套的if和check。为了使代码更简单、更优雅,有哪些常用方法


UPD:我知道在编写新项目时如何避免此类代码,但如何处理现有的遗留代码?

Bob叔叔的《干净代码》一书中提供了处理此类问题的良好指南。 就你而言,我会说:

  • 将字符串连接放入方法中(并使用
    StringBuilder
  • else{if(条件)}
    转换为
    else-if(条件)
  • 考虑将
    companyType==CompanyBean.PP\u类型&!realTraffic.isSkipOther()在一个单独的方法中,因为它似乎是某种业务逻辑,如果放在一个名为
    if(isCompanySkippedOver(companyType,realTraffic))的方法中,读者可能会更清楚
  • 考虑将
    if(realTraffic.getPvkp()!=null)
    转换为

    if(realTraffic.getPvkp() == null) {return;}
    

减少块缩进。

我不希望看到所有的字符串串联来动态生成SQL查询。您可能有一个可计数集,即使它很大。我会将它们设置为静态最终字符串,并使用
PreparedStatement
和绑定变量。您的方法太容易出错,可能会有SQL注入的风险

我会将代码保存在一个基于接口的持久性/存储库/DAO类中,我会考虑使其具有多态性,以便根据传递的参数选择版本

它真的很复杂,想想状态机、决策树或决策表。这些都是驯服复杂性的好方法


可以说OOP是为了摆脱这样的复杂逻辑。看看你是否可以使用多态性和封装来消除它。

看起来像是我每天都要处理的代码

如果我遇到一大堆类似这样的If,我会做出判断,判断未来的条件是否会改变,以及我需要在多大程度上提高代码的清晰度

如果If的主体会改变,但条件不会改变,我已经尝试将条件分解为一个返回布尔值的方法。然后,该方法将在其生命周期的一英寸内进行单元测试。我意识到这不是一个理想的重构,但它是一个实用的解决方案,可以提高该部分代码的清晰度。这可能是可行的需要指出的是,我在这里讨论的代码目前没有任何单元测试,因此大规模重构很困难-我猜你也处于类似的位置。

从编写特性测试开始,即,单元测试将修复系统的当前行为。你至少需要4个测试来覆盖所有可能的路径

只有这样,当您受到测试的保护时,您才能重构

如何重构取决于您的技术技能和倾向。作为一个面向对象的人,我可能会向封装where条件的增量构建的对象推进:

condition.add("foo = ?", x);
condition.add("bar <> ?", y);
... 
condition.toSql(); // returns the sql code
condition.getObjects(); // returns a list of x, y...
condition.add(“foo=?”,x);
条件。添加(“条?”,y);
... 
condition.toSql();//返回sql代码
condition.getObjects();//返回x,y。。。
其他方法也可能奏效


关键思想是分离抽象级别;在一个级别上,您有从数据库中选择内容的业务规则;在更具体的级别上,您有字符串连接。您不想混合这些级别。

您已经有了一个标签:通过重构。开始将块提取到私有方法中,它将压缩基本方法,并使其更易于遵循和查看可以改进的小步骤,只需一步一步地重构它。在这种情况下,您可能可以对所有这些字符串使用
StringBuilder
,而不是
+
。+1表示“小步骤”:只要对你注意到的每一件小事继续进行小而无脑的重构。我这样做不仅仅是为了清理代码,而是在我试图理解它之前。你调用
getStaticTableName()
多次。使用
Extract Local vVariable
将其减少为仅一个调用。但是,这种情况会发生变化吗?也许它应该显示为SELECT语句的teh FROM子句?