這是本文件的舊版!
Observer使用Lambda寫法進行通知的例外處理 (Working)
Introduction
這是一段常見的Observer寫法的程式碼,FileWatcher是Subject負責確認檔案是否修改,而IFileChangedListener是Observer接收檔案改變通知;當檔案改變時,FileWatcher會執行doOnChange通知各個IFileChangedListener:
public class FileWatcher extends FileWatchdog { private List<IFileChangedListener> listeners = new ArrayList<>(); static private Logger logger = LoggerFactory.getLogger(FileWatcher.class); public FileWatcher(String filename) { super(filename); } @Override protected void doOnChange() { try { if( listeners == null || listeners.isEmpty() ) return; String newContent = new String(Files.readAllBytes(Paths.get(super.filename))); listeners.forEach(listener->listener.update(newContent)); } catch( IOException e ){ throw new RuntimeException(e); } } public void addListener(IFileChangedListener listener){ listeners.add(listener); } }假設我有10個listener,當第三個listener執行update時發生了例外,工作是不是就會停止了呢? 答案是肯定的。本篇主要分享可能的例外處理方式。
Handle Exception With A Block
最直接的方法就是把例外處理弄成一個區塊:
listeners.forEach(listener->{ try { listener.update(newContent); } catch( Exception e ) { logger.warn("Update file info failed.", e); } });但隨著不同例外處理需求或流程,會變得難以閱讀而喪失原本Lambda的美意。
Extract Exception Handling As A Method
以Lambda方式實作時,將處理抽成method以增加可讀性是常使用的做法:
listeners.forEach(listener->updateEx(listener, newContent)); private void updateEx(IFileChangedListener listener, String newContent){ try { listener.update(newContent); } catch( Exception e ) { logger.warn("Update file info failed.", e); } }接下來就是考慮重複使用的議題。