先发帖
通常,我們編寫代碼來計算出一堆可用的答案。 讓我們看看Java中的情況。
public Widget getAppropriateWidget(CustomerRequest request) { if (shelfstock.contains(request.getBarcode()) { return new ShelfWidget(); } if (backroomStock.contains(request.getBarcode()) { return new BackroomWidget(); } if (supplier.contains(request.getEan()) { return new SupplierWidget(); } return null ; }您將不得不想象更復雜的場景,隱藏在上面的簡化代碼后面。 該算法的作用是按優先級順序嘗試選項,直到找到有效的選項,否則將失敗,在這種情況下它將不返回任何內容。
我們還要想象一下,由于某些原因,對contains的調用很昂貴–也許每個對象都隱藏了一個Web服務或復雜的數據庫查詢。
讓我們以兩種方式重構上面的代碼開始。 讓我們使用Optional ,并為每個方法使用子例程。
public Optional<Widget> getAppropriateWidget(CustomerRequest request) { Optional<Widget> shelfWidget = getShelfWidget(request); if (shelfWidget.isPresent()) { return shelfWidget; } Optional<Widget> backroomWidget = getBackroomWidget(request); if (backroomWidget.isPresent()) { return backroomWidget; } Optional<Widget> supplierWidget = getSupplierWidget(request); if (supplierWidget.isPresent()) { return supplierWidget; } return Optional.empty; } // imagine the subsidiary functions因此,這比未找到的返回null要好于null ,并且正努力使用子例程來使該函數描述自身,但是存在這樣一個問題,即返回的每個Optional對象都無法鏈接到責任鏈。
我們可以作弊:
Optional<Widget> shelfWidget = getShelfWidget(request); Optional<Widget> backroomWidget = getBackroomWidget(request); Optional<Widget> supplierWidget = getSupplierWidget(request); return firstNonEmpty(shelfWidget, backroomWidget, supplierWidget); private static Optional<Widget> firstNonEmpty( Optional<Widget> ... options) { return Arrays.stream(options) .filter(Optional::isPresent) .findFirst() // makes an optional of optional here... .orElse(Optional.empty()); }上面的代碼更好一些,但是現在必須在選擇一個之前預先計算所有可能的答案。 如果答案很快就會出現,我們就需要避免成本高昂的期權計算。
帶有可選解決方案的第一個過去的帖子
將流或varargs數組傳遞給一個函數,該函數由將提供可選參數的對象組成。 如果它們中的任何一個提供非空值,則獲勝。
// calling code public Optional<Widget> getAppropriateWidget(CustomerRequest request) { return firstAvailable(() -> getShelfWidget(request), () -> getBackroomWidget(request), () -> getSupplierWidget(request)); } // this is a general purpose solution // feel free to use it @SafeVarargs private static <T> Optional<T> firstAvailable( Supplier<Optional<T>> ... options) { return Arrays.stream(options) .map(Supplier::get) .filter(Optional::isPresent) .findFirst() .orElse(Optional.empty()); }翻譯自: https://www.javacodegeeks.com/2019/11/first-past-the-post.html
總結
- 上一篇: linux的vim命令大全(vim li
- 下一篇: 调低备案价好处(调低备案价)