# Pattern / solution for Boolean decision making chains

I need a solution for decision making chain. There are number of criteria that may return true, false or be inconclusive. A non-functional code (Java) would look like this:

``````Boolean res = nullValuesCheck(fieldValue, node);
if (res != null) {
return res;
}
res = typeCheck(node);
if (res != null) {
return res;
}
res = dictCheck(dict, fieldValue);
if (res != null) {
return res;
}
return finalCheck(fieldName, fieldValue); //also returns a Boolean
``````

I'm considering creating an extended predicate that would return a nullable `Boolean` instead of `boolean`, so that an inconclusive result could be returned.

I tried googling, but found no apparent solution (got lot of mishits on some simple java problems instead). I am wondering whether there exists a pattern, a library maybe, that would handle this problem properly. The problem seems generic and simple to solve and someone must've solved it already. I don't want to reinvent the wheel.

• What you're describing sounds like Trinary Logic, you might be able to find more by searching for that! Commented Sep 28, 2020 at 11:52

I think you're looking for `Optional.or()`. As in:

``````check1()
.or(() -> check2())
.or(() -> check3())
.orElse(false)
``````

Checks return `Optional<Boolean>`, so `Optional.empty()` if they don't decide, otherwise they contain the boolean decision. Result of the whole thing is a boolean with the first decision that was not empty, or the default value at the end if all were empty.

Your chain is a collection of checks, so why not treat it as such?

``````public interface ICheck
{
bool? Execute();
}

public class NullValuesCheck : ICheck
{
public NullValuesCheck(Value fieldValue, Node node)
{
//set fields
}

public bool? Execute()
{
// use fields
}
}

public class CheckCollection
{
public CheckCollection(params ICheck[] checks)
{
//save the collection
}

public bool? Execute()
{
bool? result = null;
foreach (var check in checks)
{
result = check.Execute();
if (result != null)
{
return result;
}
}
return result;
}
}

return new CheckCollection(
new NullValuesCheck(fieldValue, node),
new TypeCheck(node),
//...
).Execute();
``````

That way, you avoid repeating the "check result and execute next if null" logic everywhere you have a chain of checks, and can define your chain in a more OO way. The example above is in C#, but I think the Java implementation would be fairly similar.

• I have no problem making my own implementation, I wanted to know whether an implementation already exists and/or the pattern has na name. But thanks for your time! Commented Sep 28, 2020 at 12:55

It's not quite clear why you need a fancier solution than what you've already sketched out. Is the list of checks long or dynamic or something?

You could return `Optional<Boolean>` instead of `Boolean` to make it clear the methods might not return a result. Then you could use `Optional.or`like suggested in another answer.

If you have to deal with a long or dynamic list of checks then you could write a function that returns the first present result from a List of Suppliers:

``````<T> Optional<T> firstPresentResult(List<Supplier<Optional<T>>> suppliers) {
return suppliers.stream()
.map(x -> x.get())
.filter(x -> x.isPresent())
.findFirst()
.orElse(Optional.empty());
}
``````

Alternatively you could iterate:

``````<T> Optional<T> firstPresentResult(List<Supplier<Optional<T>>> suppliers) {
for (Supplier<Optional<T>> s: suppliers) {
if (s.get().isPresent()) {
return s.get();
}
}
return Optional.empty();
}
``````

Then you could feed the method with a list of checks

``````return firstPresentResult(
Arrays.asList(
() -> nullValuesCheck(fieldValue, node),
() -> typeCheck(node),
() -> dictCheck(dict, fieldValue),
() -> finalCheck(fieldName, fieldValue)
)
);
``````

It can be reduced to one expression with

``````Boolean res;
return ((res= nullValuesCheck(fieldValue, node)) != null)
? res
: ((res= typeCheck(node)) != null)
? res
: ((res= dictCheck(dict, fieldValue)) != null)
? res
: finalCheck(fieldName, fieldValue);
``````
• I wouldn't do this to my worst enemy. Commented Sep 28, 2020 at 17:03