日发帖 发帖频率 发帖时段
通常,我们编写代码来计算出一堆可用的答案。 让我们来看一下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
是不发现的回报,正努力使用子程序,使这个功能描述了自身,但它具有与每个的事实麻烦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
日发帖 发帖频率 发帖时段