Извлечение общего фрагмента кода в Java

1

Я новичок в 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 в зависимости от условия внутри метода. Я бы очень признателен за любую помощь.

  • 0
    Чего ты пытаешься достичь? Какой объект вы хотите создать внутри вашего метода? Каков ваш метод, что он должен принимать в качестве параметров, и что он должен возвращать?
  • 0
    Извините, если что-то упустил из вашего вопроса, я просто не совсем понял
Показать ещё 3 комментария
Теги:
oop
refactoring

1 ответ

1

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));
   ....
  • 0
    Чтобы быть полностью педантичным, должно быть два перечисления (или перечисление и карта). Плохо, что мое перечисление связано с представлением операции (например, + является дополнением), поэтому карта, в которой вы получаете Operations.ADD из + , будет лучше.
  • 0
    Проблема в том, что x (или current_priority) также зависит от символа операции, и, как я понял, ваш код требует, чтобы он был установлен, прежде чем знать, что это за символ
Показать ещё 1 комментарий

Ещё вопросы

Сообщество Overcoder
Наверх
Меню