有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java如何使其更具可读性和更清晰?

我想知道我能做些什么,使这更可读和干净。我所说的可读性,是指对其他开发人员来说更容易阅读

我真的不想让相同的代码重复两次。我在想,我可以做一些方法或方法,使它更短,但我不完全确定

@Override
public void dispatchEvent(Event event) {
    checkNotNull(event);

    CancellableEvent cancellableEvent = null;
    boolean cancellable;
    if (cancellable = event instanceof CancellableEvent) {
        cancellableEvent = (CancellableEvent) event;
        checkArgument(cancellableEvent.isCancelled());
    }

    // Ignore-cancellation event handlers will run
    for (EventPriority priority : EventPriority.values()) {
        Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, true);
        if (internalMapping != null) {
            for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                try {
                    entry.getKey().invoke(entry.getValue(), event);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    /*
                     * Delegate any exceptions that occur from
                     * the method to a runtime exception.
                     */
                    throw new RuntimeException(e);
                }
            }
        }
    }

    // Event handlers that consider cancellation will run
    for (EventPriority priority : EventPriority.values()) {
        Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, false);
        if (internalMapping != null) {
            for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                try {
                    entry.getKey().invoke(entry.getValue(), event);
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    /*
                     * Delegate any exceptions that occur from
                     * the method to a runtime exception.
                     */
                    throw new RuntimeException(e);
                }
                // Immediately return in the case of the event being cancelled.
                if (cancellable && cancellableEvent.isCancelled()) {
                    return;
                }
            }
        }
    }
}

共 (6) 个答案

  1. # 1 楼答案

    您可以将条目的调用重构到另一个方法中

    private final void invokeEntry(Entry<Method, EventListener> entry, Event event) {
        try {
            entry.getKey().invoke(entry.getValue(), event);
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (IllegalArgumentException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            /*
             * Delegate any exceptions that occur from
             * the method to a runtime exception.
             */
            throw new RuntimeException(e);
        }
    }
    

    然后,您可以使用以下方法替换dispatchEvent方法:

    @Override
    public void dispatchEvent(Event event) {
        checkNotNull(event);
    
        CancellableEvent cancellableEvent = null;
        boolean cancellable;
        if (cancellable = event instanceof CancellableEvent) {
            cancellableEvent = (CancellableEvent) event;
            checkArgument(cancellableEvent.isCancelled());
        }
    
        // Ignore-cancellation event handlers will run
        for (EventPriority priority : EventPriority.values()) {
            Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, true);
            if (internalMapping != null) {
                for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                    invokeEntry(entry, event);
                }
            }
        }
    
        // Event handlers that consider cancellation will run
        for (EventPriority priority : EventPriority.values()) {
            Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, false);
            if (internalMapping != null) {
                for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                    invokeEntry(entry, event);
                    // Immediately return in the case of the event being cancelled.
                    if (cancellable && cancellableEvent.isCancelled()) {
                        return;
                    }
                }
            }
        }
    }
    
  2. # 2 楼答案

    切勿在if条件下执行作业。这很容易出错:

    if (cancellable = event instanceof CancellableEvent) {
        ...
    }
    

    只要这样做:

    boolean cancellable = event instanceof CancellableEvent;
    if (cancellable) {
        ...
    }
    
  3. # 3 楼答案

    我假设你真正想做的是消除这两个循环。我只需要对其进行暴力,并提取一个包含所有必要参数的方法,例如:

      @Override
      public void dispatchEvent(Event event) {
          checkNotNull(event);
    
          CancellableEvent cancellableEvent = null;
          boolean cancellable;
          if (cancellable = event instanceof CancellableEvent) {
              cancellableEvent = (CancellableEvent) event;
              checkArgument(cancellableEvent.isCancelled());
          }
    
         fireEvents(false, event, cancellableEvent, cancellable);
         fireEvents(true, event, cancellableEvent, cancellable);
    
      }
    
      private void fireEvents(boolean considerCancellation, Event event, CancellableEvent cancellableEvent, boolean cancellable)
      {
         // Event handlers that consider cancellation will run
         for (EventPriority priority : EventPriority.values()) {
             Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, ! considerCancellation);
             if (internalMapping != null) {
                 for (Map.Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                     try {
                         entry.getKey().invoke(entry.getValue(), event);
                     } catch (IllegalAccessException e) {
                         e.printStackTrace();
                     } catch (IllegalArgumentException e) {
                         e.printStackTrace();
                     } catch (InvocationTargetException e) {
                         /*
                          * Delegate any exceptions that occur from
                          * the method to a runtime exception.
                          */
                         throw new RuntimeException(e);
                     }
                     // Immediately return in the case of the event being cancelled.
                     if ( considerCancellation && cancellable && cancellableEvent.isCancelled()) {
                         return;
                     }
                 }
             }
         }
      }
    

    然后可以重构新的fireEvents方法并将其清理干净

  4. # 4 楼答案

    关于使某些代码更具可读性,有什么建议?好代码和干净代码的一个度量标准是众所周知的:类应该尽可能小,方法应该尽可能小

    假设这样,您可以进行一些“提取方法”重构和提取,例如:

    ProcessSignoreCancellationEventHandlers(); ProcessEventHandlerSwithPossibleConcellation()

    如果可能的话,我会更进一步,用不同的输入参数创建一个方法,比如:

    ProcessEventHandler(NoCancellationEventHandler); processEventHandlers(CancellationAwareEventHandlers)

    这样,您将获得两项成就:

    • 更简单、更简短、更可读的代码
    • 没有重复
  5. # 5 楼答案

    没有更多的上下文很难知道,但这里有一些想法

    • 对于这两个循环,您的for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {循环似乎是相同的。我会把它放进它自己的方法中。它将接受一个Map并完成整个循环。那么你们两个for循环会小得多

      private void runMap(Map<Method, EventListener> methodMap) {
          for (Entry<Method, EventListener> entry : methodMap.entrySet()) {
             ...
          }
      }
      

      然后,您可以执行一个循环:

      for (EventPriority priority : EventPriority.values()) {
         runMap(getRegistry().getMethodMap(event.getClass(), priority, true));
         runMap(getRegistry().getMethodMap(event.getClass(), priority, false));
      }
      
    • 当你在一个包含整个循环的if (internalMapping != null) {循环中做某事时,我倾向于使用if (internalMapper == null) continue;。这会降低缩进级别

    • 已经提到了异常处理。您还可以先处理InvocationTargetException,然后再处理它下面的catch (Exception e),以便将其余的全部打印出来

  6. # 6 楼答案

    如果您正在谈论异常,那么在Java7中,您可以加入异常

    这是一篇关于Working with Java7 Exception的文章

    } catch (ParseException | IOException exception) {
    // handle I/O problems.
    }
    

    关于迭代,您可以使用单独的方法来调用功能