我试图找出使用VAVR的Try的惯用方法。我正在查看的用例必须执行以下步骤:
-获取鞋的列表(调用可以引发选中的异常)
-清理每个鞋(调用可以引发选中的异常)
-还原每个鞋(调用可以引发选中的异常)
-返回清理/还原的鞋的列表
这是我的示例玩具代码,其中processRequest方法购买n双鞋,清洗
// definitions
ShoeStore java.util.List<Shoe> buy(int numberOfPairs) throws OutOfStockException;
ShoeCleaningService Shoe clean(Shoe dirtyShoe) throws OutOfShoePolishException;
ShoeRestoreService Shoe restore(Shoe oldShoe) throws OutOfSparePartsException;
class EnterpriseShoeService {
// constructor
...
public List<Shoe> processRequest(int numberOfPairs) {
Try<List<Shoe>> shoes = Try.of(() -> shoeStore.buy(numberOfPairs));
Try<List<Try<Shoe>>> cleanedAndRestoredShoes = shoes.map(xs -> xs.stream().map(shoe ->
Try.success(shoe)
.andThenTry(shoeCleaningService::clean)
.andThenTry(shoeRestoreService::restore))
.collect(Collectors.toList()));
List<Shoe> result = cleanedAndRestoredShoes
.getOrElseGet(err -> {
System.out.println(err.getMessage());
return Collections.emptyList();
})
.stream()
.map(shoeTry -> shoeTry.onFailure(err -> System.out.println(err.getMessage())))
.filter(Try::isSuccess)
.map(Try::get)
.collect(Collectors.toList());
return result;
}
}
我的问题是:如何简化这种逻辑?是否存在可以消除的方法调用?是否可以提高可读性?
我不知道是否一切都像预期的那样工作,因为没有提到任何要求,但这应该会让您了解分解的威力。
import io.vavr.collection.List;
import io.vavr.control.Try;
public class TryListComposition {
ShoeStore store;
ShoeCleaningService cleaningService;
ShoeRestoreService restoreService;
public java.util.List<Shoe> processRequest(int numberOfPairs) {
return processShoesRequest(numberOfPairs).getOrElse(List.empty()).toJavaList();
}
public Try<List<Shoe>> processShoesRequest(int numberOfPairs) {
return this.buy(numberOfPairs)
.map(shoes -> shoes
.map(this::cleanAndRestore)
.flatMap(x -> x)
);
}
public Try<Shoe> cleanAndRestore(Shoe shoe) {
return clean(shoe).flatMap(this::restore);
}
Try<List<Shoe>> buy(int numberOfPairs) {
return Try.of(() ->
List.ofAll(store.buy(numberOfPairs).stream());
}
Try<Shoe> clean(Shoe dirtyShoe) {
return Try.of(() -> cleaningService.clean(dirtyShoe));
}
Try<Shoe> restore(Shoe oldShoe) {
return Try.of(() -> restoreService.restore(oldShoe));
}
}
class Shoe {
}
interface ShoeStore {
java.util.List<Shoe> buy(int numberOfPairs) throws
OutOfStockException;
}
interface ShoeCleaningService {
Shoe clean(Shoe dirtyShoe) throws OutOfShoePolishException;
}
interface ShoeRestoreService {
Shoe restore(Shoe oldShoe) throws OutOfSparePartsException;
}
class OutOfStockException extends Exception {
}
class OutOfShoePolishException extends Exception {
}
class OutOfSparePartsException extends Exception {
}
Java 8 的对象函数式扩展,目标是减少代码行数,提高代码质量,提供了持久化集合、错误处理函数式抽象、模式匹配等等。 Vavr 融合了面向对象编程的强大功能,具有功能编程的优雅性和坚固性。 最有趣的部分是拥有功能丰富且持久的集合库,可以与 Java 的标准集合顺利集成。
如果现有的特征测试不能完成你所需要的工作,你就必须编写一个新的。这些宏是创建模块。它们为其它宏提供了检查各种 特征是否存在并且报告结果的方式。 本章包括一些建议和一些关于现有的测试的为什么要那样编写的原因。通过阅读现有的测试,你还可以学到许多关于编写 Autoconf测试的方法。如果在一个或多个Autoconf测试中出现了错误,这些信息可以帮助你理解它们意味着什么,这有助 于你找到最佳的解决问题的
由于你写的大部分 Redux 代码是函数,而且其中大部分是纯函数,所以很好测,不需要模拟。 准备工作 我们推荐使用 Jest) 作为测试引擎,需要注意的是 Jest 运行在 Node 环境中,因此你不能访问 DOM。 npm install --save-dev jest 如果想要和 Babel 一起使用,还需要安装 babel-jest npm install --save-dev babel-
假设我们编写了一个hello.js,并且输出一个简单的求和函数: // hello.js module.exports = function (...rest) { var sum = 0; for (let n of rest) { sum += n; } return sum; }; 这个函数非常简单,就是对输入的任意参数求和并返回结果。 如
我有一个简单的方法(使用jooq),基本上是这样做的: 在表'MY_OBJECT'中,我有一个字段'id',其定义为: 每当我运行上面提到的代码时,都会出现错误: 在我看来,问题是jOOq试图将值写入标识列。MyConvertor将其保留为null的原因是,该值将由db生成。如何使jooq不尝试向该字段写入null?
测试用来验证非测试的代码是否按照期望的方式运行的 Rust 函数。测试函数体通常执行如下三种操作: 设置任何所需的数据或状态 运行需要测试的代码 断言其结果是我们所期望的 让我们看看 Rust 提供的专门用来编写测试的功能:test 属性、一些宏和 should_panic 属性。 作为最简单例子,Rust 中的测试就是一个带有 test 属性注解的函数。属性(attribute)是关于 Rust