Reputation: 876
I have a Java class like below
class MyClass {
public boolean rule1() {...}
public boolean rule2() {...}
public boolean rule3() {...}
}
now for instance I want to check the rule of above class in many ways such as :
MyClass myClass = new MyClass();
if (myClass.rule1() && myClass.rule2 || myClass.rule3) {}
and Now I am wondering that how can I implement above line with like this one?
if (myClass.rule1().and().rule2().or().rule3().accept()) {}
Upvotes: 2
Views: 101
Reputation: 51403
The cleaner way would be to use the functional interface Predicate:
Type Parameters:
T - the type of the input to the predicate Functional Interface: This is a functional interface and can therefore be used as the assignment target for a lambda expression or method reference.
public class A {
public Predicate rule1() {
return //some operation that returns a boolean;
}
public Predicate rule2() {
return //some operation that returns a boolean;
}
public Predicate rule3() {
return //some operation that returns a boolean;
}
}
But the if
chain of method calls would not look like you are looking for, namely:
if (myClass.rule1().and().rule2().or().rule3().accept()) {}
Otherwise, you would have to implement the Builder pattern, and implement the and(), or(), and accept methods. For instance:
public class BooleanEvaluator {
List<String> rules = new ArrayList<>();
public BooleanEvaluator and() {
rules.add("&&");
return this;
}
public BooleanEvaluator or() {
rules.add("or");
return this;
}
public boolean accept() {
int i = 0;
boolean result = Boolean.parseBoolean(rules.get(0));
while (i < rules.size() - 1) {
if(rules.get(i).equals("&&")){
result = result && Boolean.parseBoolean(rules.get(i + 1));
i+=2;
}
else if(rules.get(i).equals("||")){
result = result || Boolean.parseBoolean(rules.get(i + 1));
i+=2;
}
}
return false;
}
public BooleanEvaluator rule1() {
boolean result = // apply the rule 1
rules.add(String.valueOf(result));
return this;
}
public BooleanEvaluator rule2() {
boolean result = // apply the rule 2
rules.add(String.valueOf(result));
return this;
}
public BooleanEvaluator rule3() {
boolean result = // apply the rule 3
rules.add(String.valueOf(result));
return this;
}
void some_method(){
if (this.rule1().and().rule2().or().rule3().accept()) {
// ...
}
}
}
Naturally, the accept
method would have to be much more robust, this is just to show what would the design look like.
Upvotes: 1
Reputation: 49606
Have a look at Predicate<T>
and its and
or or
.
MyClass instance = new MyClass();
Predicate<MyClass> predicate = MyClass::rule1;
if (predicate.and(MyClass::rule2).or(MyClass::rule3).test(instance)) {
// todo
}
It might look less readable than the version you mentioned, renaming MyClass
to something more meaningful would help. If it doesn't work for you, consider writing a Builder. Good complex examples of which can be found in, let's say, dynamic SQL builders (for example, jooq).
Upvotes: 1