Я новичок в Java, и я делаю калькулятор синтаксического анализа строки. У меня есть фрагмент кода, который содержит несколько почти одинаковых фрагментов, которые мне хотелось бы извлечь в какой-то метод или около того, но я не мог придумать, как это сделать.
Вот фрагмент кода:
case '+':
current_priority = 1;
if (last_priority < current_priority) {
i++;
first_operand = new Add(first_operand, parse(expression, current_priority));
} else {
i--;
return first_operand;
}
break;
case '*':
current_priority = 2;
if (last_priority < current_priority) {
i++;
first_operand = new Multiply(first_operand, parse(expression, current_priority));
} else {
i--;
return first_operand;
}
break;
case '/':
current_priority = 2;
if (last_priority < current_priority) {
i++;
first_operand = new Divide(first_operand, parse(expression, current_priority));
} else {
i--;
return first_operand;
}
break;
Я хотел бы получить метод или что-то, что скопирует поведение следующего фрагмента:
current_priority = x;
if (last_priority < current_priority) {
i++;
first_operand = new Something(first_operand, parse(expression, current_priority));
} else {
i--;
return first_operand;
}
Проблема в том, что, насколько мне известно, я не могу объявить неинициализированные объекты в Java, и для моей программы важно не запускать конструктор Something (Add/Multiply/Divide), прежде чем убедиться, что это действительно необходимо, поэтому передача объекта в этот метод не является способом, я должен каким-то образом создать объект внутри этого метода, но это, похоже, приводит к созданию двух переключателей с одинаковыми случаями, и я хотел бы, если возможно, более элегантное решение. Я также не знаю, как воспроизвести поведение return/assign в зависимости от условия внутри метода. Я бы очень признателен за любую помощь.
A Использование Factory
current_priority = x;
if (last_priority < current_priority) {
i++;
first_operand = myOperationFactory.createOperand(operation, first_operand, parse(expression, current_priority));
} else {
i--;
return first_operand;
}
public class OperationFactory {
public Operand createOperand(char operation, Operand firstOperand, Operand secondOperand) {
switch (operation) {
case '+': return new Add(firstOperand, secondOperand);
case ...
}
B (расширенный) использовать перечисление и отражение.
public enum Operations {
ADD('+', Add.class),
MULTIPLY('*', Multiply.class)
...;
private char symbol;
private Constructor<? extends Operation> constructor;
public Operations(char symbol, Class<? extends Operation> clazz) {
this.symbol = symbol;
this.constructor= clazz.getConstructor(Operand.class, Operand.class);
}
public Operation create(Operand operan1, Operand operand2) {
return constructor.newInstance(operand1, operand2);
}
public char getSymbol() {
return this.symbol;
}
public static Operations getFromSymbol(char symbol) {
for (Operations op : Operations.values()) {
if (op.getSymbol() == symbol) {
return op;
}
}
}
}
а также
current_priority = x;
if (last_priority < current_priority) {
i++;
Operations operation = Operations.fromSymbol(opSymbol);
first_operand = operation.create(first_operand, parse(expression, current_priority));
....
+
является дополнением), поэтому карта, в которой вы получаете Operations.ADD
из +
, будет лучше.