for-loop + Arrow Anti Pattern VS for-loop + continue

时间:2015-09-23 08:58:26

标签: java design-patterns anti-patterns

您认为以下代码片段(for-loop + continue)

for (Identity fileIdentity : fileIdentities) {
      totalFileCount++;
      if (!forceTheStatus(params, fileIdentity))
        continue;
      updatedFileCount++;
      if (!params.shouldUpdateLinkedEntity())
        continue;
      Optional<Identity> batchIdentity = getLinkedBatchIdentity(fileIdentity);
      if (!batchIdentity.isPresent())
        continue;
      totalBatchCount++;
      if (!getRemittanceProcessor().forceTheStatus(params, batchIdentity.get()))
        continue;
      updatedBatchCount++;
}

比其他更好(for-loop + Arrow Anti Pattern)?为什么?

for (Identity fileIdentity : fileIdentities) {
      totalFileCount++;
      if (forceTheStatus(params, fileIdentity)) {
        updatedFileCount++;
        if (params.shouldUpdateLinkedEntity()) {
          Optional<Identity> batchIdentity = getLinkedBatchIdentity(fileIdentity);
          if (batchIdentity.isPresent()) {
            totalBatchCount++;
            if (getRemittanceProcessor().forceTheStatus(params, batchIdentity.get()))
              updatedBatchCount++;
          }
        }
      }
}

对我来说,使用continue的解决方案看起来更难以理解,但另一方面我们有一个反模式:(

2 个答案:

答案 0 :(得分:4)

两种解决方案都不可读。不要使用continue,也不要在一个方法中创建太多嵌套ifs。

我建议:

  1. 将您的代码拆分为
  2. 小部件
  3. 文档您的代码
  4. 尝试使用有意义的名称
  5. 当然,我不明白你的方法和变量是做什么的,但我试图创建一个虚构的例子,重构的,记录的代码可能是这样的:

    import java.util.Arrays;
    import java.util.Optional;
    
    public class Snippet {
    
        /** The total number of all files, that were inspected */
        private int totalFileCount;
    
        /** The number of files that have been modified in any kind of way */
        private int updatedFileCount;
    
        /** The number of files, that were put into batch processing */
        private int totalBatchCount;
    
        /** The number of files, that have successfully been processed by the batch */
        private int updatedBatchCount;
    
        /** inspects all files, processes them, if required */
        private void processFiles(Parameters params, Iterable<Identity> fileIdentities) {
            for (Identity fileIdentity : fileIdentities)
                processFile(params, fileIdentity);
        }
    
        /** inspects a single file, processes it, if required */
        private void processFile(Parameters params, Identity fileIdentity) {
            totalFileCount++;
            if (forceTheStatus(params, fileIdentity))
                updateFile(params, fileIdentity);
        }
    
        /** updates the file, and - if necessary - updates the linked entity */
        private void updateFile(Parameters params, Identity fileIdentity) {
            updatedFileCount++;
            if (params.shouldUpdateLinkedEntity())
                updateLinkedEntity(params, fileIdentity);
        }
    
        /** puts the linked entity into the batch processing queue (if any exists) */
        private void updateLinkedEntity(Parameters params, Identity fileIdentity) {
            Optional<Identity> batchIdentity = getLinkedBatchIdentity(fileIdentity);
            if (batchIdentity.isPresent())
                batchUpdateLinkedEntity(params, batchIdentity);
        }
    
        /**
          * puts the linked entity into the batch processing queue
          * and uses the remittance processor
          */
        private void batchUpdateLinkedEntity(Parameters params, Optional<Identity> batchIdentity) {
            totalBatchCount++;
            if (getRemittanceProcessor().forceTheStatus(params, batchIdentity.get()))
                updatedBatchCount++;
        }
    
        // Dummy implementations to make the code compilable
    
        public static class Parameters {
            public boolean shouldUpdateLinkedEntity() {
                return false;
            }
        }
    
        public static class Identity {
        }
    
        public static void main(String[] args) {
            Iterable<Identity> fileIdentities = Arrays.asList(new Identity());
            new Snippet().processFiles(new Parameters(), fileIdentities);
        }
    
        private Snippet getRemittanceProcessor() {
            return null;
        }
    
        private Optional<Identity> getLinkedBatchIdentity(Identity fileIdentity) {
            return null;
        }
    
        private boolean forceTheStatus(Object params, Identity fileIdentity) {
            return false;
        }
    }
    

答案 1 :(得分:1)

我投票继续。但是你可以将状态映射到枚举然后使用switch / case?