Imagine a Person class with a boolean flag indicating whether or not the person is employable - set to false by default.
public class Person{
boolean employable = false;
...
}
Now imagine having some external boolean methods which act on Person objects. For example, consider static boolean methods in a utility class.
public class PersonUtil{
public static boolean ofWorkingAge(Person p){
if(p.getAge() > 16) return true;
return false;
}
...
}
Boolean valued static methods in essence analogous to boolean valued functions i.e. predicates.
We can construct a 2^(#predicates)-by-#predicates truth table out of predicates. For example, given three predicates: ofWorkingAge, ofGoodCharacter, isQualified we can construct the following 8-by-3 truth table:
T T T
T T F
T F T
T F F
F T T
F T F
F F T
F F F
We now want to employ people with desirable qualities. Let + indicate that we wish to employ somebody (i.e. set their employability flag to true) and - the opposite.
T T T | +
T T F | +
T F T | +
T F F | -
F T T | +
F T F | -
F F T | -
F F F | -
Now imagine having a collection of Person objects. For each person we adjust their employability flag according to the three predicates. We also update a count (this forces us to use the entire truth table instead of just the positives), so that given 1,000 people we want to end up with something like:
T T T | + 100
T T F | + 200
T F T | + 50
T F F | - 450
F T T | + 50
F T F | - 50
F F T | - 50
F F F | - 50
Presumably this can be thought of as filtering with truth tables. Setting employability flags and updating counts is a rather contrived example but you can easily see how we might instead want to set and update much more complicated things.
QUESTION
Is there a way of elegantly doing this? I can think of two solutions:
Clunky solution
Have a giant hand coded if, else if, else chain.
if(ofWorkingAge && ofGoodCharacter && isQualified){
c1++;
p.setEmployable(true)
}
else if(ofWorkingAge && ofGoodCharacter && !isQualified){
c2++;
p.setEmployable(true)
}
...
else if(!ofWorkingAge && !ofGoodCharacter && isQualified){
c7++;
}
else{
c8++;
}
This is just bad.
Slightly smarter solution
Pass predicates (perhaps in an array) and a collection of sentences to a method. Let the method generate the corresponding truth table. Loop over the people, set their employability, and return an array of counts.
I can see how things could be done with functional interfaces. This SO answer could be used. You could change PrintCommand to IsQualified and pass callCommand a Person instead of a string. But this also seems kindah clunky because we'd then have to have a new interface file for every predicate we come up with.
Is there any other Java 8-ish way of doing this?
Aucun commentaire:
Enregistrer un commentaire