![自动发帖](https://i-blog.csdnimg.cn/blog_migrate/6321f0f3cbbab8ae6517aefc38389e5c.png)
自动发帖
通常,我们编写代码来计算出一堆可用的答案。 让我们看看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
自动发帖