Los consumidores combinar con diferentes argumentos o diferentes argumentos numéricos

Aleksey Balenko:

Vamos a decir, nuestro método recibe entrada de cadena y devuelve alguna lista de salida . Esta salida es el resultado de un cierto número de generadores, algunos de los cuales dependen de la entrada y algunos de ellos no - que sólo se suman los valores predefinidos. Quiero poner en práctica estos generadores como una lista de algunas interfaces de función (por ejemplo, al Consumidor), luego combinarlos en un solo Consumidor y aplicarlo a la cadena de entrada.

Por lo tanto, voy a poder cambiar pequeños generadores fácil y de forma independiente. Pero el problema es que no todos mis generadores necesitan entrada de cadena como parámetro y acabo de pasar este parámetro no sólo por una razón - tener una capacidad de combinar estos consumidores con los demás.

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");
}}

¿Es posible combinar diferentes consumidores bajo un mismo paraguas y las aplican en un solo lugar? O esto es una mala idea y no la forma correcta de hacer tales cosas?

Holger:

No es un patrón inusual de tener una interfaz común en un software modular y adaptadores , para hacer implementaciones particulares encajan. P.ej

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");
    }
}

Así ignoreFirstArges el adaptador general para métodos no tener ese primer parámetro. Puede haber un número arbitrario de métodos de adaptador. Pero tenga en cuenta que si un adaptador es muy específico y por lo tanto, sólo se usan una sola vez, también es posible escribir una expresión lambda en lugar de un método de referencia, justo en el código de la combinación. Tenga en cuenta que he cambiado ese código, no se evalúan varias veces para cada generate(String input)llamada, de lo contrario, no habría ningún punto en la combinación de ellos cuando no emplee la función combinada, como lo haría también el uso

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;
}

o incluso más sencillo

List<String> generate(String input) {
    ArrayList<String> output = new ArrayList<>();

    this.addFirstDependent(input, output);
    this.addSecondIndependent(output);

    return output;
}

que no es peor de mantener que el código funcional, como sigue, cada generador consiste en una sola línea.

Supongo que te gusta

Origin http://43.154.161.224:23101/article/api/json?id=119591&siteId=1
Recomendado
Clasificación