fluent接口

xnifntxz  于 2021-07-06  发布在  Java
关注(0)|答案(2)|浏览(468)

我正在为工作建立一个springboot项目。在这个项目中,我有一个服务,负责从另一个后端获取某些文档。在很多不同的情况下,文档必须满足某些标准,例如从某个日期开始,可以自由匹配。目前,这是通过以下常规方法实现的:

@Service
public class DocumentService(){

  private OtherService otherService;

  @Autowire
  public DocumentService(OtherService otherService){
    this.otherService = otherService;
  }

  public List<Document> getDocuments() {
   ...
  }

  public List<Document> getDocuments(LocalDate date) {
   ...
  }

  public List<Document> getDocuments(String name){
   ...
  }

  public List<Document> getDocuments(String name, LocalDate date){
   ...
  }

}

我发现这是一个相当糟糕的解决方案,因为每一个新的组合都需要一个新的方法。出于这个原因,我想使用一个流畅风格的界面,比如:

//Some other class that uses DocumentService
documentService().getDocuments().withDate(LocalDate date).withName(String name).get();

我熟悉构建器模式和方法链接,但我不知道如何适应其中任何一种。根据我的理解,@服务类在springboot中是单例的。
这在所有可能的 Spring 启动?

vc9ivgsu

vc9ivgsu1#

如果您想在这里使用fluent接口,那么 getDocuments() 方法必须是方法链的起点。或许可以创造一个 DocumentFilter 类,然后你会得到这样的结果:

documentService.documents().getDocuments().withDate(LocalDate date).withName(String name).getDocuments()

在本例中,您的 DocumentFilter 会有 withDate(...) 以及 withName(...) 方法,并且每个后续调用都包括前面调用中的所有条件 DocumentFilter .

brtdzjyr

brtdzjyr2#

不必是spring引导解决方案,为什么不引入类似于本地类的pojo构建器:

@Service
public class DocumentService(){
    public Builder documents() {
        return new Builder();
    }

    public class Builder {
        private LocalDate date;
        private String name;

        public Builder withDate(LocalDate date) {
            this.date = date;
            return this;
        }

        // etc

        public List<String> get() {
            final List<SomeDTO> results = otherService.doQuery(name, date, ...);
            // TODO - tranform DTO to List<String>
            return list;
        }
    }
}

显然,如果它不需要访问父组件,就将其设置为静态。
您可以使spring组件和构建器成为同一个对象,但这确实让人感觉有些做作,而且我希望您能够支持多个构建器。
另外,我假设父组件是一个真正的服务,也就是说,它不包含任何状态或变体,否则会带来潜在的同步问题。
编辑:只是为了举例说明,生成器维护了要传递给 otherService 并执行任何类似转换的服务。

相关问题