Java VAVR编写尝试列表

Java VAVR编写尝试列表,java,functional-programming,vavr,Java,Functional Programming,Vavr,我试图找出使用VAVR的Try的惯用方法。 我正在研究的用例必须遵循以下步骤: -获取鞋的列表(调用可能引发选中的异常) -清理每个鞋子(调用可能引发选中的异常) -还原每个鞋(调用可能引发选中的异常) -返回已清洁/修复的鞋的列表 这是我的示例玩具代码,processRequest方法购买n双鞋,清洗并恢复它们;打印错误(如果有): // definitions ShoeStore java.util.List<Shoe> buy(int numberOfPairs) throws

我试图找出使用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;

    }
}

//定义
ShoeStore java.util.List buy(int numberOfPairs)抛出StockException;
鞋清洁服务鞋清洁(鞋脏鞋)扔掉鞋油;
鞋店服务鞋修复(旧鞋)扔出配件感觉;
一流企业服务{
//建造师
...
公共列表processRequest(int numberOfPairs){
试穿鞋子=试穿(()->鞋店购买(数量对));
尝试cleanedAndRestoredShoes=shoes.map(xs->xs.stream().map(shoe->
尝试。成功(鞋)
.入口(shoeCleaningService::clean)
.Entry(shoeRestoreService::restore))
.collect(Collectors.toList());
列表结果=已清理和已清理的鞋子
.getOrElseGet(错误->{
System.out.println(err.getMessage());
返回集合。emptyList();
})
.stream()
.map(shoeTry->shoeTry.onFailure(err->System.out.println(err.getMessage()))
.filter(尝试::isSuccess)
.map(Try::get)
.collect(Collectors.toList());
返回结果;
}
}

我的问题是:这一逻辑如何简化?是否存在可以消除的方法调用?可读性可以提高吗?

我不知道是否一切都像预期的那样工作,因为没有提到任何要求,但这应该让您了解分解的威力

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 {

}
导入io.vavr.collection.List;
导入io.vavr.control.Try;
公共类TryListComposition{
鞋店;
鞋清洁服务清洁服务;
鞋店服务恢复服务;
public java.util.List processRequest(int numberOfPairs){
返回processShoesRequest(numberOfPairs.getOrElse(List.empty()).toJavaList();
}
公共Try进程shoesrequest(int numberOfPairs){
退回这个。购买(numberOfPairs)
.map(鞋->鞋
.map(此::cleanAndRestore)
.flatMap(x->x)
);
}
公共商店(鞋){
返回clean(shoe).flatMap(this::restore);
}
试买(整数对){
返回尝试次数(()->
所有(store.buy(numberOfPairs.stream())的列表;
}
尝试清洁(鞋子脏鞋子){
返回(()->清洁服务清洁(脏鞋))的尝试;
}
尝试恢复(旧鞋){
返回(()->restoreService.restore(oldShoe))的尝试;
}
}
职业鞋{
}
界面鞋底{
java.util.List buy(int numberOfPairs)抛出
库存外异常;
}
界面清理服务{
鞋清洁(鞋脏鞋)扔掉鞋油;
}
接口ShoeRestoreService{
鞋修复(鞋旧鞋)摆脱了部件异常;
}
类OutOfStockException扩展了异常{
}
类OutofShopPolysHexException扩展了异常{
}
类OutOfParePartsException扩展了异常{
}

我喜欢你用一个玩具示例来突出你所面临的问题,但要从你试图实现的代码中进行逆向工程仍然有点困难。除了发布你最终得到的代码外,你还可以添加一个需求列表。也许有一些要点是你希望看到的e是取鞋时的一个错误,如果在清洁/恢复鞋子时出现错误怎么办?如果某些鞋子出现错误,但不是所有鞋子都出现错误(短路),您希望如何汇总结果鞋子的列表。我认为您应该首先关注此解决方案想要的接口。如果没有足够的鞋子,会发生什么?是全部还是全部没有?您将问题标记为函数编程-关于这一点,您至少应该将您的函数拆分为多个命名良好的函数。例如->返回类型表示否sens因为您只筛选成功的请求,所以列表将只包含列表。我们可以从returing类型中删除此Try包装器。类型在FP中很重要-您的示例中充满了编译错误。我已经有多个函数:buy、clean、restore。现在我想实现的是以可读的方式组合它们。类似于:buy().flatMap(shoes->shoes.stream).map(shoe->clean(shoe)).map(shoe->restore(shoe)).collect(list)。我的动机是编写一个可读的解决方案。在Java中,lambda表达式和选中的异常很难编写,所以我正在查看选项(al),也可以试试。