Редактирование на основе комментариев
Вы должны определенно реализовать изменяемые и неизменяемые классы отдельно.Имена методов могут быть похожими или разными, это не имеет значения, так как интерфейсы будут отличаться в любом случае.
Один класс
Стратегия изменчивости может быть упомянута в качестве дополнительного аргумента метода, например:
apply(a,b,Operation.ADD, ResultValue.NEW)
apply(a,b,Operation.ADD, ResultValue.FIRST_ARG)
apply(a,b,Operation.ADD, ResultValue.SECOND_ARG)
Однако использование нескольких стратегий в одном методе приведет к путанице для клиентов и будет подвержено ошибкам.
Если подпись метода
double [] apply(double[] arg1, double[] arg2, BinaryOperation)
тогда изменчивость или неизменность могут быть частью самой BinaryOperation:
public class FirstArgMutablePlusOperation {
double[] apply(double[] arg1, double[] arg2) {
//sample mutation
arg1[0] = arg1[0] + arg2[0];
// still return arg1 as a result
return arg1;
}
}
public class SecondArgMutablePlusOperation {
double[] apply(double[] arg1, double[] arg2) {
//sample mutation
arg2[0] = arg1[0] + arg2[0];
// still return arg2 as a result
return arg2;
}
}
public class ImmutablePlusOperation {
double[] apply(double[] arg1, double[] arg2) {
//sample mutation
double[] result = new double[arg1.length];
result[0] = arg1[0] + arg2[0];
return result;
}
}
Затем пользователь может вызвать метод apply с правильной стратегией:
apply(arg1, arg2, new FirstArgMutablePlusOperation());
apply(arg1, arg2, new SecondArgMutablePlusOperation());
double[] result = apply(arg1, arg2, new ImmutablePlusOperation());
Неизменяемая / изменяемая стратегия может бытьчасть BinaryOperation.Однако я скорее избегаю этого решения, так как оно будет представлять операторы if и громоздкую реализацию:
public enum ResultStrategy
{ RESULT, FIRST_ARG, SECOND_ARG };
public class PlusOperation extends BinaryOperation {
private final ResultStrategy strategy;
public PlusOperation(final ResultStrategy strategy) {
this.strategy = strategy
}
double[] apply(double[] arg1, double[] arg2) {
if(strategy == ResultStrategy.FIRST_ARG) {
//sample mutation
arg1[0] = arg1[0] + arg2[0];
// still return arg1 as a result
return arg1;
} else if(strategy == ResultStrategy.SECOND_ARG) {
//sample mutation
arg2[0] = arg1[0] + arg2[0];
// still return arg2 as a result
return arg2;
} else if(strategy == ResultStrategy.RESULT) {
double[] result = new double[arg1.length];
result[0] = arg1[0] + arg2[0];
return result;
}
}
}
Использование:
apply(arg1, arg2, new PlusOperation(ResultStrategy.FIRST_ARG));
apply(arg1, arg2, new PlusOperation(ResultStrategy.SECOND_ARG));
double[] result = apply(arg1, arg2, new PlusOperation(ResultStrategy.RESULT));
UPDATE
В соответствии с примером кода, приведенным в вопросе
public enum ResultStrategy { FIRST_ARG, NEW_RESULT;} // SECOND_ARG = apply(b, a)
public class DoubleArraysMath {
...
public static double[] apply(ResultStrategy rs, double[] a, double[] b, BinaryOperation o) {
if (rs == ResultStrategy.FIRST_ARG) { return apply(a, a, b, o); }
return apply(new double[a.length], a, b, o);
}
}