Condition: secondary clauses now use Supplier's to enable short circuiting

This commit is contained in:
Paul Campbell 2018-03-13 17:08:06 +00:00
parent d1ca0b039f
commit efc1705a6c
4 changed files with 88 additions and 58 deletions

View file

@ -21,6 +21,8 @@
package net.kemitix.conditional;
import java.util.function.Supplier;
/**
* If-then-else in a functional-style.
*
@ -35,7 +37,6 @@ public interface Condition {
*
* @return the Condition
*/
@SuppressWarnings("avoidinlineconditionals")
static Condition where(final boolean clause) {
return clause ? TrueCondition.TRUE : FalseCondition.FALSE;
}
@ -58,7 +59,7 @@ public interface Condition {
*
* @return the Condition
*/
Condition and(boolean clause);
Condition and(Supplier<Boolean> clause);
/**
* Logically AND combine the current {@code Condition} with boolean opposite of the clause.
@ -67,8 +68,8 @@ public interface Condition {
*
* @return the Condition
*/
default Condition andNot(final boolean clause) {
return and(!clause);
default Condition andNot(final Supplier<Boolean> clause) {
return and(() -> !clause.get());
}
/**
@ -78,8 +79,7 @@ public interface Condition {
*
* @return the Condition
*/
@SuppressWarnings("PMD.ShortMethodName")
Condition or(boolean clause);
Condition or(Supplier<Boolean> clause);
/**
* Logically OR combine the current {@code Condition} with the boolean opposite of the clause.
@ -88,8 +88,8 @@ public interface Condition {
*
* @return the Condition
*/
default Condition orNot(final boolean clause) {
return or(!clause);
default Condition orNot(final Supplier<Boolean> clause) {
return or(() -> !clause.get());
}
/**
@ -115,8 +115,8 @@ public interface Condition {
*
* @return the Condition
*/
default Condition otherwise(final boolean clause) {
return where(clause);
default Condition otherwise(final Supplier<Boolean> clause) {
return where(clause.get());
}
}

View file

@ -21,6 +21,8 @@
package net.kemitix.conditional;
import java.util.function.Supplier;
/**
* A {@code Condition} that has evaluated to {@code false}.
*
@ -31,14 +33,13 @@ final class FalseCondition implements Condition {
public static final Condition FALSE = new net.kemitix.conditional.FalseCondition();
@Override
public Condition and(final boolean clause) {
public Condition and(final Supplier<Boolean> clause) {
return FALSE;
}
@Override
@SuppressWarnings("PMD.ShortMethodName")
public Condition or(final boolean secondClause) {
return Condition.where(secondClause);
public Condition or(final Supplier<Boolean> secondClause) {
return Condition.where(secondClause.get());
}
@Override

View file

@ -21,6 +21,8 @@
package net.kemitix.conditional;
import java.util.function.Supplier;
/**
* A {@code Condition} that has evaluated to {@code true}.
*
@ -31,13 +33,12 @@ final class TrueCondition implements Condition {
public static final Condition TRUE = new net.kemitix.conditional.TrueCondition();
@Override
public Condition and(final boolean clause) {
return Condition.where(clause);
public Condition and(final Supplier<Boolean> clause) {
return Condition.where(clause.get());
}
@Override
@SuppressWarnings("PMD.ShortMethodName")
public Condition or(final boolean secondClause) {
public Condition or(final Supplier<Boolean> secondClause) {
return TRUE;
}

View file

@ -3,6 +3,8 @@ package net.kemitix.conditional;
import org.junit.Before;
import org.junit.Test;
import java.util.concurrent.atomic.AtomicInteger;
import static org.assertj.core.api.Assertions.assertThat;
/**
@ -77,7 +79,7 @@ public class ConditionalTest {
//when
Condition.where(true)
.then(thenResponse)
.and(true)
.and(() -> true)
.then(otherwiseResponse);
//then
assertThatBothResponsesRun();
@ -138,7 +140,7 @@ public class ConditionalTest {
public void whereTrueAndNotFalseThenRuns() {
//when
Condition.where(true)
.andNot(false)
.andNot(() -> false)
.then(thenResponse);
//then
assertThatTheThenResponseRuns();
@ -148,7 +150,7 @@ public class ConditionalTest {
public void whereTrueAndNotTrueThenOtherwiseRuns() {
//when
Condition.where(true)
.andNot(true)
.andNot(() -> true)
.then(thenResponse)
.otherwise(otherwiseResponse);
//then
@ -159,7 +161,7 @@ public class ConditionalTest {
public void whereFalseOrNotFalseThenRuns() {
//when
Condition.where(false)
.orNot(false)
.orNot(() -> false)
.then(thenResponse);
//then
assertThatTheThenResponseRuns();
@ -169,7 +171,7 @@ public class ConditionalTest {
public void whereFalseOrNotTrueThenOtherwiseRuns() {
//when
Condition.where(false)
.orNot(true)
.orNot(() -> true)
.then(thenResponse)
.otherwise(otherwiseResponse);
//then
@ -181,7 +183,7 @@ public class ConditionalTest {
//when
Condition.where(false)
.then(thenResponse)
.otherwise(true)
.otherwise(() -> true)
.then(otherwiseResponse);
//then
assertThatTheOtherwiseResponseRuns();
@ -192,7 +194,7 @@ public class ConditionalTest {
//when
Condition.where(false)
.then(thenResponse)
.otherwise(false)
.otherwise(() -> false)
.then(otherwiseResponse);
//then
assertThatNoResponseRuns();
@ -269,7 +271,7 @@ public class ConditionalTest {
final boolean secondClause
) {
Condition.where(firstClause)
.and(secondClause)
.and(() -> secondClause)
.then(thenResponse)
.otherwise(otherwiseResponse);
}
@ -279,8 +281,34 @@ public class ConditionalTest {
final boolean secondClause
) {
Condition.where(firstClause)
.or(secondClause)
.or(() -> secondClause)
.then(thenResponse)
.otherwise(otherwiseResponse);
}
@Test
public void shortCurcuitOr() {
//given
final AtomicInteger atomicInteger = new AtomicInteger();
//when
Condition.where(true)
.or(() -> atomicInteger.compareAndSet(0, 2))
.then(thenResponse);
//then
assertThatTheThenResponseRan();
assertThat(atomicInteger).hasValue(0);
}
@Test
public void shortCurcuitAnd() {
//given
final AtomicInteger atomicInteger = new AtomicInteger();
//when
Condition.where(false)
.and(() -> atomicInteger.compareAndSet(0, 2))
.then(thenResponse);
//then
assertThatTheThenResponseDidNotRun();
assertThat(atomicInteger).hasValue(0);
}
}