All Downloads are FREE. Search and download functionalities are using the official Maven repository.

de.team33.patterns.decision.telesto.Choice Maven / Gradle / Ivy

There is a newer version: 1.20.0
Show newest version
package de.team33.patterns.decision.telesto;

import java.util.function.Function;
import java.util.function.Predicate;

/**
 * A functional implementation of a simple decision.
 * 

* Typically used to implement multiple choices, e.g. based on an enum: *

 * public enum Result {
 *
 *     A, B, C, D, E;
 *
 *     public static Result map(final X x, final Y y, final Z z) {
 *         return Case.HEAD.apply(new Input(x, y, z));
 *     }
 *
 *     private enum Case implements Function<Input, Result> {
 *
 *         CASE_11_(Choice.on(Input::k3).reply(A).orReply(C)),
 *         CASE_10_(Choice.on(Input::k3).reply(B).orReply(E)),
 *         CASE_01_(Choice.on(Input::k3).reply(D).orReply(A)),
 *         CASE_00_(Choice.on(Input::k3).reply(D).orReply(B)),
 *         CASE_1__(Choice.on(Input::k2).apply(CASE_11_).orApply(CASE_10_)),
 *         CASE_0__(Choice.on(Input::k2).apply(CASE_01_).orApply(CASE_00_)),
 *         HEAD(Choice.on(Input::k1).apply(CASE_1__).orApply(CASE_0__));
 *
 *         private final Function<Input, Result> backing;
 *
 *         Case(Function<Input, Result> backing) {
 *             this.backing = backing;
 *         }
 *
 *         @Override
 *         public Result apply(Input input) {
 *             return backing.apply(input);
 *         }
 *     }
 *
 *     private static class Input {
 *
 *         final X x;
 *         final Y y;
 *         final Z z;
 *
 *         Input(final X x, final Y y, final Z z) {
 *             this.x = x;
 *             this.y = y;
 *             this.z = z;
 *         }
 *
 *         final boolean k1() {
 *             return x.k1();
 *         }
 *
 *         final boolean k2() {
 *             return y.k2();
 *         }
 *
 *         final boolean k3() {
 *             return z.k3();
 *         }
 *     }
 * }
 * 
* * @param

The parameter type * @param The result type * @see de.team33.patterns.decision.telesto package */ public class Choice implements Function { private final Predicate

condition; private final Function positive; private final Function negative; private Choice(final Predicate

condition, final Function positive, final Function negative) { this.condition = condition; this.positive = positive; this.negative = negative; } /** * Creates and returns a {@link Conditional} based on a given {@link Predicate condition}. * The first stage to finally build a {@link Choice}. */ public static

Conditional

on(final Predicate

condition) { return new Conditional

(condition); } @Override public final R apply(final P parameter) { return (condition.test(parameter) ? positive : negative).apply(parameter); } /** * Represents the second stage to finally build a {@link Choice}. *

* It "knows" the condition as well as its positive reaction and allows defining a negative reaction * in case the condition is false. */ @FunctionalInterface public interface Consequence { /** * Finally creates and returns a {@link Choice} based on a given {@link Function negative reaction}. */ Choice orApply(Function negative); /** * Finally creates and returns a {@link Choice} based on a given fixed value presumed as negative result. */ default Choice orReply(final R negative) { return orApply(any -> negative); } } /** * Represents the first stage to finally build a {@link Choice}. *

* It "knows" the condition and allows defining a consequence in case the condition is true. */ public static class Conditional

{ private final Predicate

condition; private Conditional(final Predicate

condition) { this.condition = condition; } /** * Creates and returns a {@link Consequence} based on a given {@link Function positive reaction}. * The second stage to finally build a {@link Choice}. */ public final Consequence apply(final Function positive) { return negative -> new Choice<>(condition, positive, negative); } /** * Creates and returns a {@link Consequence} based on a given fixed value presumed as positive result. * The second stage to finally build a {@link Choice}. */ public final Consequence reply(final R positive) { return apply(any -> positive); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy