java - 结合具有不同参数或不同参数编号的消费者
问题描述
比方说,我们的方法接收输入String 并返回一些 List output。这个输出是一些生成器的结果,其中一些依赖于输入,而一些不依赖于输入——它们只是添加预定义的值。我想像一些函数接口(例如消费者)的列表一样实现这些生成器,然后将它们组合成一个消费者并将其应用于输入字符串。
因此,我将能够轻松独立地更换小型发电机。但问题是,并不是我所有的生成器都需要输入字符串作为参数,我只是将这个参数传递给那里,原因只有一个——能够将这些消费者与其他消费者结合起来。
public class ConsumersTest {
private static <T, U> BiConsumer<T, U> combine(List<BiConsumer<T, U>> consumers) {
return consumers.stream().reduce((arg1, arg2) -> {}, BiConsumer::andThen);
}
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
combine(getGenerators()).accept(input, output);
return output;
}
private List<BiConsumer<String, List<String>>> getGenerators() {
return Arrays.asList(
this::addFirstDependent,
this::addSecondIndependent
);
}
private void addFirstDependent(String input, List<String> output) {
if (input.contains("some string")) {
output.add("First-Dependent");
}
}
private void addSecondIndependent(String input, List<String> output) {
output.add("Predefined Output");
}}
是否可以将不同的消费者组合在一个保护伞下,并将它们应用到一个地方?或者这是一个坏主意,而不是做这些事情的正确方法?
解决方案
在模块化软件和适配器中具有通用接口以使特定实现适合,这并不是一种不寻常的模式。例如
public class ConsumersTest {
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
generators.accept(input, output);
return output;
}
private static <T, U> BiConsumer<T, U> ignoreFirstArg(Consumer<U> consumer) {
return (t, u) -> consumer.accept(u);
}
private final BiConsumer<String, List<String>> generators =
Stream.<BiConsumer<String, List<String>>>of(
this::addFirstDependent,
ignoreFirstArg(this::addSecondIndependent)
).reduce(BiConsumer::andThen).orElse((arg1, arg2) -> {});
private void addFirstDependent(String input, List<String> output) {
if (input.contains("some string")) {
output.add("First-Dependent");
}
}
private void addSecondIndependent(List<String> output) {
output.add("Predefined Output");
}
}
ignoreFirstArg
没有第一个参数的方法的通用适配器也是如此。可以有任意数量的适配器方法。但请注意,如果适配器非常具体,因此只使用一次,也可以在组合代码中编写 lambda 表达式而不是方法引用。请注意,我更改了该代码,以免每次generate(String input)
调用都重复评估,否则,当您不重用组合函数时,将它们组合起来毫无意义,因为您也可以使用
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
Stream.<BiConsumer<String, List<String>>>of(
this::addFirstDependent,
ignoreFirstArg(this::addSecondIndependent)
).forEach(g -> g.accept(input, output));
return output;
}
甚至更简单
List<String> generate(String input) {
ArrayList<String> output = new ArrayList<>();
this.addFirstDependent(input, output);
this.addSecondIndependent(output);
return output;
}
这并不比功能代码更难维护,因为每个生成器都由一行组成。
推荐阅读
- android - 在 Android / NDK 中为 YUV 帧添加单色效果
- python - Python - 从两个列表的元素连接创建多个列表
- html - 如何在 Leaflet HTML 中将经度和纬度转换为(地址/物理)
- go - 我是否需要在生产服务器上安装所有 go 依赖包
- java - QAF:java.lang.IllegalArgumentException:必须定义添加操作的键
- java - 使用 JNDI 使用 Spring Boot 配置多个数据源
- esri-maps - Android ESRI地图如何从屏幕点获取纬度经度
- sql - 如果日期落在 29,30 和 31,则将日期转换为下个月
- r - 在 ggplot2-plot 的标题中包含特定日期
- apache-kafka - Confluent Cloud 上没有模式验证