用Java提取公共代码片段

时间:2015-04-12 19:58:39

标签: java oop refactoring

我是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)在确定它真正需要之前,你应该将对象传递给这个方法,我不得不以某种方式在这个方法中创建一个对象,但这似乎导致两个开关具有相同的情况和如果可能,我想要更优雅的解决方案。我也不知道如何根据方法内的条件重现返回/赋值行为。我真的很感激任何帮助。

1 个答案:

答案 0 :(得分: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));
   ....