简体   繁体   English

我怎样才能让它更具可读性和清洁度?

[英]How can I make this more readable and cleaner?

I am wondering what I can do to make this more readable and clean. 我想知道我能做些什么才能让它更具可读性和清洁性。 By readable, I mean easier to read for other developers. 通过可读,我的意思是更容易阅读其他开发人员。

I don't really want to have the same code twice. 我真的不想两次使用相同的代码。 I am thinking that I could make some method or methods to make it shorter, but I'm not exactly sure... 我想我可以制作一些方法或方法来缩短它,但我不确定......

@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;
                }
            }
        }
    }
}

If you are talking about exceptions then in java 7 you can club exceptions. 如果您正在讨论异常,那么在Java 7中您可以使用异常。

Here is the article about Working with Java7 Exception 这是关于使用Java7异常的文章

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

About Iterations you can have separate method for invoke functionality. 关于迭代,您可以使用单独的方法来调用功能。

What to recommend about making some code more readable? 有什么建议让一些代码更具可读性? One of the metric of nice and clean code is known for long time: class should be as small as possible, methods should be as small as possible. 很长一段时间都知道好的和干净的代码之一:类应该尽可能小,方法应该尽可能小。

Assuming this you could do some "extract method" refactoring and extract for example: 假设你可以做一些“提取方法”重构和提取,例如:

processIgnoreCancellationEventHandlers(); processIgnoreCancellationEventHandlers(); processEventHandlersWithPossibleCancellation(); processEventHandlersWithPossibleCancellation();

I would go even further and make one method with different input params if possible, something like: 如果可能的话,我会更进一步,使用不同的输入参数制作一个方法,例如:

processEventHandlers(noCancellationEventHandlers); processEventHandlers(noCancellationEventHandlers); processEventHandlers(CancellationAwareEventHandlers); processEventHandlers(CancellationAwareEventHandlers);

This way you will have two achievements: 这样你就会有两个成就:

  • more simple, short and readable code, 更简单,简洁,可读的代码,
  • no duplication. 没有重复。

Hard to know without more context but here are some thoughts. 没有更多的背景很难知道,但这里有一些想法。

  • Your for (Entry<Method, EventListener> entry : internalMapping.entrySet()) { loop seems to be the same for both loops. 您的for (Entry<Method, EventListener> entry : internalMapping.entrySet()) { loop似乎对于两个循环都是相同的。 I would put that into it's own method. 我会把它放到它自己的方法中。 It would take in a Map and it would do the entire loop. 它将采用Map ,它将完成整个循环。 Then you two for-loops would be much smaller. 那么你们两个for循环会小得多。

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

    Your could then do one loop: 然后你可以做一个循环:

     for (EventPriority priority : EventPriority.values()) { runMap(getRegistry().getMethodMap(event.getClass(), priority, true)); runMap(getRegistry().getMethodMap(event.getClass(), priority, false)); } 
  • When you are doing something in a loop where if (internalMapping != null) { which encompasses the whole loop then I tend to use if (internalMapper == null) continue; 当你在循环中做一些if (internalMapping != null) {包含整个循环然后我倾向于使用if (internalMapper == null) continue; . That reduces the indent levels. 这减少了缩进级别。

  • The exception handling has been mentioned. 已经提到了异常处理。 You can also handle the InvocationTargetException first, and then catch (Exception e) below it for all of the rest to print out. 您还可以先处理InvocationTargetException ,然后在它下面catch (Exception e) ,以便打印出所有其余部分。

I'm assuming that what you really want to do is eliminate those two loops. 我假设你真正想做的就是消除这两个循环。 I would just brute force it and extract a method containing all the necessary arguments for example: 我只是强制它并提取一个包含所有必要参数的方法,例如:

  @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;
                 }
             }
         }
     }
  }

Then you can refactor the new fireEvents method and clean it up. 然后你可以重构新的fireEvents方法并清理它。

Never do assignments in if-conditions. 永远不要在if条件下进行分配。 This is error-prone: 这很容易出错:

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

Just do this: 这样做:

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

You can refactor the invocation of an entry into another method. 您可以将条目的调用重构为另一种方法。

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);
    }
}

Then you can replace your dispatchEvent method with this: 然后你可以用这个替换你的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;
                }
            }
        }
    }
}

As the loops are identical except the one boolean, I'd start by splitting them like this, then break them down further if required. 由于除了一个布尔值之外的循环是相同的,我首先将它们分开,然后根据需要进一步分解它们。

@Override
public void dispatchEvent(Event event) {
    checkNotNull(event);
    CancellableEvent cancellableEvent = null;
    boolean cancellable;
    if (cancellable = event instanceof CancellableEvent) {
        cancellableEvent = (CancellableEvent) event;
        checkArgument(cancellableEvent.isCancelled());
    }
    handleEvents(event, true);
    handleEvents(event, false, cancellableEvent);
}

public void handleEvents(Event event, boolean cancellable)
{
    handleEvents(event, cancellable, null);
}

public void handleEvents(Event event, boolean cancellable, CancellableEvent cancellableEvent)
{
    for (EventPriority priority : EventPriority.values()) {
        Map<Method, EventListener> internalMapping = getRegistry().getMethodMap(event.getClass(), priority, cancellable);
        if (internalMapping != null) {
            for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {
                try {
                    entry.getKey().invoke(entry.getValue(), event);
                } catch (IllegalAccessException | 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 (cancellableEvent != null && cancellable && cancellableEvent.isCancelled()) {
                    return;
                }
            }
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM