2012-09-26 53 views
2

我想知道我可以做些什麼來使這更可讀和乾淨。通過閱讀,我的意思是更容易閱讀其他開發人員。我怎樣才能使這更可讀和更清潔?

我真的不想有兩次相同的代碼。我想,我可以做一些方法或方法,從而使它更短,但我不能完全確定......

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

一開始,你可以替換一個多抓,像多個catch語句:'趕上(拋出:IllegalArgumentException | IllegalAccessException E)' 。注意或使用按位包含而不是邏輯或。 – MrLore

+1

您可以將try/catch重構爲另一個方法'invokeEntry(Entry entry)',並從兩個for循環中調用它。 – jalynn2

+1

你不應該真的在真實代碼 –

回答

2

我假設你真正想做的事就是消除這兩個循環。我只想蠻力它,並提取包含所有必要參數的方法。例如:

@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方法和清理。

3

如果你在談論的例外則在Java 7,您可以例外俱樂部。

下面是一篇關於Working with Java7 Exception

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

關於迭代,你可以有調用的功能單獨的方法。

+0

我知道這一點,但我想要針對Java 6.真正的問題是,我正在寫迭代兩次和東西... –

2

什麼建議使一些代碼更具可讀性?好的和乾淨的代碼的度量標準之一是已知的很長一段時間:類應儘可能小,方法應儘可能小。

假設這個你可以做一些「提取方法」重構並提取例如:

processIgnoreCancellationEventHandlers(); processEventHandlersWithPossibleCancellation();

我會再進一步​​,使一個方法具有不同的輸入PARAMS如果可能的話,是這樣的:

processEventHandlers(noCancellationEventHandlers); processEventHandlers(CancellationAwareEventHandlers);

這種方式,您將有兩個成就:

  • 更簡單,簡短和可讀的代碼,
  • 沒有重複。
2

很難知道沒有更多的上下文,但這裏有一些想法。

  • 你的for (Entry<Method, EventListener> entry : internalMapping.entrySet()) {循環似乎是兩個循環相同。我會把它放到它自己的方法中。這將需要在Map,它會做整個循環。那麼你的兩個for-loops會小得多。

    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)以便其餘的打印出來。

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; 
       } 
      } 
     } 
    } 
} 
+0

調用是很好的突圍。循環和'internalMapping'讀取也可以被打破。 – user1201210

1

由於循環除了一個布爾值之外都是相同的,所以我會先將它們拆分成這樣,然後根據需要進一步拆分它們。

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

從不在if條件下進行分配。這是容易出錯:

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

只是這樣做:

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

我同意if條件下的作業。因爲稍後會用到''cancel'',所以需要在第二個'if'中設置。 – user1201210

+0

@Dynguss你說得對。沒有看到。 –

+0

...但我會重構這種可取消的使用。因爲if-condition的第二部分是NPE候選人,所以當你必須考慮2個角時,如果可以取消,那麼它在這裏不能爲空。它應該只是'cancellableEvent!= null && ...' –

相關問題