Вероятно, вы уже поняли, что я собираюсь сделать. Собрав все текущее поведение компоновки аргументов в базовом классе ArgumentMarshaler, я намерен перемещать его вниз в производные классы. Это позволит мне сохранить работоспособность программы в ходе постепенного изменения ее структуры.
Очевидным следующим шагом стало перемещение функциональности аргумента int в ArgumentMarshaler. И снова все обошлось без сюрпризов:
private Map
new HashMap
...
private void parseIntegerSchemaElement(char elementId) {
intArgs.put(elementId, new IntegerArgumentMarshaler());
}
...
private void setIntArg(char argChar) throws ArgsException {
currentArgument++;
String parameter = null;
try {
parameter = args[currentArgument];
intArgs.get(argChar).setInteger(Integer.parseInt(parameter));
} catch (ArrayIndexOutOfBoundsException e) {
valid = false;
errorArgumentId = argChar;
errorCode = ErrorCode.MISSING_INTEGER;
throw new ArgsException();
} catch (NumberFormatException e) {
valid = false;
errorArgumentId = argChar;
errorParameter = parameter;
errorCode = ErrorCode.INVALID_INTEGER;
throw new ArgsException();
}
}
...
public int getInt(char arg) {
Args.ArgumentMarshaler am = intArgs.get(arg);
return am == null ? 0 : am.getInteger();
}
...
private class ArgumentMarshaler {
private boolean booleanValue = false;
private String stringValue;
private int integerValue;
public void setBoolean(boolean value) {
booleanValue = value;
}
public boolean getBoolean() {
return booleanValue;
}
public void setString(String s) {
stringValue = s;
}
public String getString() {
return stringValue == null ? "" : stringValue;
}
public void setInteger(int i) {
integerValue = i;
}
public int getInteger() {
return integerValue;
}
}
Переместив всю логику компоновки аргументов в ArgumentMarshaler, я занялся перемещением функциональности в производные классы. На первом этапе я должен был переместить функцию setBoolean в BooleanArgumentMarshaller и позаботиться о том, чтобы она правильно вызывалась. Для этого был создан абстрактный метод set.
private abstract class ArgumentMarshaler {
protected boolean booleanValue = false;
private String stringValue;
private int integerValue;
public void setBoolean(boolean value) {
booleanValue = value;
}
public boolean getBoolean() {
return booleanValue;
}
public void setString(String s) {
stringValue = s;
}
public String getString() {
return stringValue == null ? "" : stringValue;
}
public void setInteger(int i) {
integerValue = i;
}
public int getInteger() {
return integerValue;
}
public abstract void set(String s);
}
Затем метод set был реализован в BooleanArgumentMarshaller.
private class BooleanArgumentMarshaler extends ArgumentMarshaler {
public void set(String s) {
booleanValue = true;
}
}
Наконец, вызов setBoolean был заменен вызовом set.
private void setBooleanArg(char argChar, boolean value) {
booleanArgs.get(argChar).set("true");
}
Все тесты прошли успешно. Так как изменения привели к перемещению set в BooleanArgumentMarshaler, я удалил метод setBoolean из базового класса ArgumentMarshaler.