Condition: secondary clauses now use Supplier's to enable short circuiting
This commit is contained in:
parent
d1ca0b039f
commit
efc1705a6c
4 changed files with 88 additions and 58 deletions
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
package net.kemitix.conditional;
|
package net.kemitix.conditional;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* If-then-else in a functional-style.
|
* If-then-else in a functional-style.
|
||||||
*
|
*
|
||||||
|
@ -35,7 +37,6 @@ public interface Condition {
|
||||||
*
|
*
|
||||||
* @return the Condition
|
* @return the Condition
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("avoidinlineconditionals")
|
|
||||||
static Condition where(final boolean clause) {
|
static Condition where(final boolean clause) {
|
||||||
return clause ? TrueCondition.TRUE : FalseCondition.FALSE;
|
return clause ? TrueCondition.TRUE : FalseCondition.FALSE;
|
||||||
}
|
}
|
||||||
|
@ -58,7 +59,7 @@ public interface Condition {
|
||||||
*
|
*
|
||||||
* @return the 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.
|
* Logically AND combine the current {@code Condition} with boolean opposite of the clause.
|
||||||
|
@ -67,8 +68,8 @@ public interface Condition {
|
||||||
*
|
*
|
||||||
* @return the Condition
|
* @return the Condition
|
||||||
*/
|
*/
|
||||||
default Condition andNot(final boolean clause) {
|
default Condition andNot(final Supplier<Boolean> clause) {
|
||||||
return and(!clause);
|
return and(() -> !clause.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -78,8 +79,7 @@ public interface Condition {
|
||||||
*
|
*
|
||||||
* @return the Condition
|
* @return the Condition
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("PMD.ShortMethodName")
|
Condition or(Supplier<Boolean> clause);
|
||||||
Condition or(boolean clause);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Logically OR combine the current {@code Condition} with the boolean opposite of the 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
|
* @return the Condition
|
||||||
*/
|
*/
|
||||||
default Condition orNot(final boolean clause) {
|
default Condition orNot(final Supplier<Boolean> clause) {
|
||||||
return or(!clause);
|
return or(() -> !clause.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -115,8 +115,8 @@ public interface Condition {
|
||||||
*
|
*
|
||||||
* @return the Condition
|
* @return the Condition
|
||||||
*/
|
*/
|
||||||
default Condition otherwise(final boolean clause) {
|
default Condition otherwise(final Supplier<Boolean> clause) {
|
||||||
return where(clause);
|
return where(clause.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
package net.kemitix.conditional;
|
package net.kemitix.conditional;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code Condition} that has evaluated to {@code false}.
|
* 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();
|
public static final Condition FALSE = new net.kemitix.conditional.FalseCondition();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Condition and(final boolean clause) {
|
public Condition and(final Supplier<Boolean> clause) {
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("PMD.ShortMethodName")
|
public Condition or(final Supplier<Boolean> secondClause) {
|
||||||
public Condition or(final boolean secondClause) {
|
return Condition.where(secondClause.get());
|
||||||
return Condition.where(secondClause);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -21,6 +21,8 @@
|
||||||
|
|
||||||
package net.kemitix.conditional;
|
package net.kemitix.conditional;
|
||||||
|
|
||||||
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A {@code Condition} that has evaluated to {@code true}.
|
* 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();
|
public static final Condition TRUE = new net.kemitix.conditional.TrueCondition();
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Condition and(final boolean clause) {
|
public Condition and(final Supplier<Boolean> clause) {
|
||||||
return Condition.where(clause);
|
return Condition.where(clause.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@SuppressWarnings("PMD.ShortMethodName")
|
public Condition or(final Supplier<Boolean> secondClause) {
|
||||||
public Condition or(final boolean secondClause) {
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,6 +3,8 @@ package net.kemitix.conditional;
|
||||||
import org.junit.Before;
|
import org.junit.Before;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
import static org.assertj.core.api.Assertions.assertThat;
|
import static org.assertj.core.api.Assertions.assertThat;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -76,9 +78,9 @@ public class ConditionalTest {
|
||||||
public void whereTrueThenDoSomethingAndThenDoSomethingElse() {
|
public void whereTrueThenDoSomethingAndThenDoSomethingElse() {
|
||||||
//when
|
//when
|
||||||
Condition.where(true)
|
Condition.where(true)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.and(true)
|
.and(() -> true)
|
||||||
.then(otherwiseResponse);
|
.then(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatBothResponsesRun();
|
assertThatBothResponsesRun();
|
||||||
}
|
}
|
||||||
|
@ -119,7 +121,7 @@ public class ConditionalTest {
|
||||||
public void whereNotFalseThenRuns() {
|
public void whereNotFalseThenRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.whereNot(false)
|
Condition.whereNot(false)
|
||||||
.then(thenResponse);
|
.then(thenResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheThenResponseRuns();
|
assertThatTheThenResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -128,8 +130,8 @@ public class ConditionalTest {
|
||||||
public void whereNotTrueThenOtherwiseRuns() {
|
public void whereNotTrueThenOtherwiseRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.whereNot(true)
|
Condition.whereNot(true)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.otherwise(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheOtherwiseResponseRuns();
|
assertThatTheOtherwiseResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -138,8 +140,8 @@ public class ConditionalTest {
|
||||||
public void whereTrueAndNotFalseThenRuns() {
|
public void whereTrueAndNotFalseThenRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(true)
|
Condition.where(true)
|
||||||
.andNot(false)
|
.andNot(() -> false)
|
||||||
.then(thenResponse);
|
.then(thenResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheThenResponseRuns();
|
assertThatTheThenResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -148,9 +150,9 @@ public class ConditionalTest {
|
||||||
public void whereTrueAndNotTrueThenOtherwiseRuns() {
|
public void whereTrueAndNotTrueThenOtherwiseRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(true)
|
Condition.where(true)
|
||||||
.andNot(true)
|
.andNot(() -> true)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.otherwise(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheOtherwiseResponseRuns();
|
assertThatTheOtherwiseResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -159,8 +161,8 @@ public class ConditionalTest {
|
||||||
public void whereFalseOrNotFalseThenRuns() {
|
public void whereFalseOrNotFalseThenRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(false)
|
Condition.where(false)
|
||||||
.orNot(false)
|
.orNot(() -> false)
|
||||||
.then(thenResponse);
|
.then(thenResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheThenResponseRuns();
|
assertThatTheThenResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -169,9 +171,9 @@ public class ConditionalTest {
|
||||||
public void whereFalseOrNotTrueThenOtherwiseRuns() {
|
public void whereFalseOrNotTrueThenOtherwiseRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(false)
|
Condition.where(false)
|
||||||
.orNot(true)
|
.orNot(() -> true)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.otherwise(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheOtherwiseResponseRuns();
|
assertThatTheOtherwiseResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -180,9 +182,9 @@ public class ConditionalTest {
|
||||||
public void whereFalseElseTrueThenOtherwiseRuns() {
|
public void whereFalseElseTrueThenOtherwiseRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(false)
|
Condition.where(false)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(true)
|
.otherwise(() -> true)
|
||||||
.then(otherwiseResponse);
|
.then(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatTheOtherwiseResponseRuns();
|
assertThatTheOtherwiseResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -191,9 +193,9 @@ public class ConditionalTest {
|
||||||
public void whereFalseElseFalseThenNothingRuns() {
|
public void whereFalseElseFalseThenNothingRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(false)
|
Condition.where(false)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(false)
|
.otherwise(() -> false)
|
||||||
.then(otherwiseResponse);
|
.then(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatNoResponseRuns();
|
assertThatNoResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -202,8 +204,8 @@ public class ConditionalTest {
|
||||||
public void whereTrueChainedThensBothRuns() {
|
public void whereTrueChainedThensBothRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(true)
|
Condition.where(true)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.then(otherwiseResponse);
|
.then(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatBothResponsesRun();
|
assertThatBothResponsesRun();
|
||||||
}
|
}
|
||||||
|
@ -212,8 +214,8 @@ public class ConditionalTest {
|
||||||
public void whereFalseChainedThensNothingRuns() {
|
public void whereFalseChainedThensNothingRuns() {
|
||||||
//when
|
//when
|
||||||
Condition.where(false)
|
Condition.where(false)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.then(otherwiseResponse);
|
.then(otherwiseResponse);
|
||||||
//then
|
//then
|
||||||
assertThatNoResponseRuns();
|
assertThatNoResponseRuns();
|
||||||
}
|
}
|
||||||
|
@ -235,22 +237,22 @@ public class ConditionalTest {
|
||||||
|
|
||||||
private void assertThatTheOtherwiseResponseRan() {
|
private void assertThatTheOtherwiseResponseRan() {
|
||||||
assertThat(otherwiseFlag).as("otherwise response runs")
|
assertThat(otherwiseFlag).as("otherwise response runs")
|
||||||
.isTrue();
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatTheThenResponseRan() {
|
private void assertThatTheThenResponseRan() {
|
||||||
assertThat(thenFlag).as("then response runs")
|
assertThat(thenFlag).as("then response runs")
|
||||||
.isTrue();
|
.isTrue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatTheOtherwiseResponseDidNotRun() {
|
private void assertThatTheOtherwiseResponseDidNotRun() {
|
||||||
assertThat(otherwiseFlag).as("otherwise response does not run")
|
assertThat(otherwiseFlag).as("otherwise response does not run")
|
||||||
.isFalse();
|
.isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatTheThenResponseDidNotRun() {
|
private void assertThatTheThenResponseDidNotRun() {
|
||||||
assertThat(thenFlag).as("then response does not run")
|
assertThat(thenFlag).as("then response does not run")
|
||||||
.isFalse();
|
.isFalse();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertThatNoResponseRuns() {
|
private void assertThatNoResponseRuns() {
|
||||||
|
@ -260,27 +262,53 @@ public class ConditionalTest {
|
||||||
|
|
||||||
private void when(final boolean clause) {
|
private void when(final boolean clause) {
|
||||||
Condition.where(clause)
|
Condition.where(clause)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.otherwise(otherwiseResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void when(
|
private void when(
|
||||||
final boolean firstClause,
|
final boolean firstClause,
|
||||||
final boolean secondClause
|
final boolean secondClause
|
||||||
) {
|
) {
|
||||||
Condition.where(firstClause)
|
Condition.where(firstClause)
|
||||||
.and(secondClause)
|
.and(() -> secondClause)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.otherwise(otherwiseResponse);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void whenOr(
|
private void whenOr(
|
||||||
final boolean firstClause,
|
final boolean firstClause,
|
||||||
final boolean secondClause
|
final boolean secondClause
|
||||||
) {
|
) {
|
||||||
Condition.where(firstClause)
|
Condition.where(firstClause)
|
||||||
.or(secondClause)
|
.or(() -> secondClause)
|
||||||
.then(thenResponse)
|
.then(thenResponse)
|
||||||
.otherwise(otherwiseResponse);
|
.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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue