Nehmen wir mal als Beispiel eine ganz einfache DSL für Vergleichsoperationen (meiner Meinung nach eine der misslungensten Java-APIs).
Welchen Stil würdet ihr vorziehen, und warum? Oder würdet ihr es ganz anders machen?
1) Einzelne Argumente, Operatoren als Methoden
boolean b1 = is(3).lessThan(5);
boolean b2 = is(3).greaterOrEqual(3);
boolean b3 = using(Comparator.<String>reverseOrder()).is("z").lessThan("a");
Implementierung:
[SPOILER]
public final class Ord<T> {
private final T firstValue;
private final Comparator<? super T> comparator;
private Ord(T firstValue, Comparator<? super T> comparator) {
this.firstValue = firstValue;
this.comparator = comparator;
}
static <T extends Comparable<? super T>> Ord<T> is(T firstValue) {
return new Ord<>(firstValue, Comparator.naturalOrder());
}
interface Using<T> {
Ord<T> is(T firstValue);
}
static <T> Using<T> using(Comparator<? super T> comparator) {
return value -> new Ord<>(value, comparator);
}
public boolean equalTo(T secondValue) {
return comparator.compare(firstValue,secondValue) == 0;
}
public boolean lessThan(T secondValue) {
return comparator.compare(firstValue,secondValue) < 0;
}
public boolean lessOrEqual(T secondValue) {
return comparator.compare(firstValue,secondValue) <= 0;
}
public boolean greaterThan(T secondValue) {
return comparator.compare(firstValue,secondValue) > 0;
}
public boolean greaterOrEqual(T secondValue) {
return comparator.compare(firstValue,secondValue) >= 0;
}
}
[/SPOILER]
2) Mehrere Argumente inklusive Operatoren
boolean b1 = is(3, lessThan, 5);
boolean b2 = is(3, greaterOrEqual, 3);
boolean b3 = using(Comparator.<String>reverseOrder()).is("z", lessThan, "a");
Implementierung:
[spoiler]
public enum Ord {
lessThan(i -> i < 0),
lessOrEqual(i -> i <= 0),
equalTo(i -> i == 0),
greaterOrEqual(i -> i >= 0),
greaterThan(i -> i > 0);
private final Predicate<Integer> pred;
Ord(Predicate<Integer> pred) {
this.pred = pred;
}
public static <T extends Comparable<? super T>> boolean is(T firstValue, Ord ord, T secondValue) {
return ord.pred.test(firstValue.compareTo(secondValue));
}
public static <T> Using<T> using(Comparator<? super T> comparator) {
return (first, ord, second) -> ord.pred.test(comparator.compare(first,second));
}
public interface Using<T> {
boolean is(T firstValue, Ord ord, T secondValue);
}
}
[/spoiler]