У меня есть следующие сообщения proto3:
message Condition {
oneof value {
bool booleanLiteral = 1; /** True/False */
BinaryCondition binaryCondition = 2;
UnaryCondition unaryCondition = 3;
}
}
message BinaryCondition {
enum Operator {
AND = 0; /** Boolean AND */
OR = 1; /** Boolean OR */
}
Operator operator = 1; /** A valid operator that joins 2 conditions */
Condition firstOperand = 2; /** The first condition */
Condition secondOperand = 3; /** The second condition */
}
message UnaryCondition {
enum Operator {
NOT = 0; /** Boolean NOT */
}
Operator operator = 1; /** A valid operator that modifies the value of 1 condition */
Condition operand = 2;/** The condition subject to modification */
}
Вопрос
Учитывая объект Java 11 Condition, я должен оценить базовое логическое выражение . Как мне разработать классы и интерфейсы для оценки? У меня есть 2 идеи. Может ли кто-нибудь подсказать мне лучший подход или проверить мои подходы?
Мои подходы
Я придумал 2 способа моделирования класса Evaluator:
- Несколько перегруженных функций
evaluate
с разными типами и подтипами Condition
в качестве параметра в одном классе. - Несколько классов, переопределяющих реализацию по умолчанию
evaluate
в общем c базовый класс. Это решение представляет собой сочетание стратегии и фабричного шаблона.
Фрагмент, соответствующий второму подходу:
class Evaluator<T> {
protected T condition;
protected Evaluator(final T condition) {
this.condition = condition;
}
public static Evaluator<?> newInstance(final Object condition) {
if (condition instanceof Condition) {
return new ConditionEvaluator((Condition) condition);
} else if (condition instanceof BinaryCondition) {
return new BinaryConditionEvaluator((BinaryCondition) condition);
} else if (condition instanceof UnaryCondition) {
return new UnaryConditionEvaluator((UnaryCondition) condition);
} else {
return new Evaluator<Boolean> (false);
}
}
public boolean evaluate() {
return false;
}
}
class ConditionEvaluator extends Evaluator<Condition> {
public ConditionEvaluator(final Condition condition) {
super(condition);
}
@Override
public boolean evaluate() {
// Switch case code can be replaced by using field descriptors instead.
if (condition.hasBinaryCondition()) {
return Evaluator.newInstance(condition.getBinaryCondition()).evaluate();
} else if (condition.hasUnaryCondition()) {
return Evaluator.newInstance(condition.getUnaryCondition()).evaluate();
} else {
return condition.getBooleanLiteral();
}
}
}
class BinaryConditionEvaluator extends Evaluator<BinaryCondition> {
public BinaryConditionEvaluator(final BinaryCondition condition) {
super(condition);
}
@Override
public boolean evaluate() {
final Evaluator<?> firstEvaluator = Evaluator.newInstance(condition.getFirstOperand());
final Evaluator<?> secondEvaluator = Evaluator.newInstance(condition.getSecondOperand());
switch (condition.getOperatorValue()) {
case BinaryCondition.Operator.AND_VALUE:
return firstEvaluator.evaluate() && secondEvaluator.evaluate();
case BinaryCondition.Operator.OR_VALUE:
return firstEvaluator.evaluate() || secondEvaluator.evaluate();
default:
return false;
}
}
}