Соглашение об именовании изменяемых / неизменяемых методов - PullRequest
0 голосов
/ 12 июня 2018

Каково соглашение об именах, когда у вас есть два метода с общим именем, выполняющие одну и ту же операцию , в то время как один неизменный , а другой * изменяемый ?

ПРИМЕР

Рассмотрим операцию по ячейкам, принимающую 2 массива чисел: неизменяемая версия создает новый массив для помещения результата, тогда как изменяемая версия сохраняет результат в первом параметре массива.

Поскольку имя метода является чем-то общим, например apply, поскольку стратегия операции (add, sub, mul, div) определяется третьим аргументом, вы не можете использовать общие слова, такие как add, для изменчивости (a =a + 1) и plus для неизменности (c = a + b).

КОД (БУДЕТ ПРОПИСАН)

Следующие детали могут быть оффтопными, но дляиллюстрация о том, о каком методе я говорю:

@FunctionalInterface 
public interface BinaryOperation { double apply(double a, double b); }

public final class BinaryOperations {
    private BinaryOperations() {}

    public static final BinaryOperation ADD = (a, b) -> a + b;
    public static final BinaryOperation SUB = (a, b) -> a - b;
    public static final BinaryOperation MUL = (a, b) -> a * b;
    public static final BinaryOperation DIV = (a, b) -> a / b;
}

public final class DoubleArraysMath {
    private DoubleArrayMath() {}

    // ---> METHOD NAME OF INTEREST
    public static void applyAsMutable(double[] a, double[] b, BinaryOperation o) {
        apply(a, a, b, o);
    }
    // ---> METHOD NAME OF INTEREST
    public static double[] applyAsImmutable(double[] a, double[] b, BinaryOperation o) {
        double[] c = new double[a.length];
        return apply(c, a, b, o);
        return c;
    }
    private static void apply(double[] result, double[] a, double[] b, BinaryOperation o) {
        for (int i = 0; i < a.length; i++) { result[i] = o.apply(a[i], b[i]); }
    }
}

// just an example of usage
double[] r = DoubleArraysMath.applyAsImmutable(a, b, BinaryOperations.MUL);
DoubleArraysMath.applyAsMutable(a, b, BinaryOperations.ADD);
DoubleArraysMath.applyAsMutable(a, b, (ai, bi) -> ai*ai + bi); // some custom operation

ОТДЕЛЬНЫЕ КЛАССЫ

Разделение изменяемых и неизменяемых методов в классах DoubleArraysMutableMath и DoubleArraysImmutableMath позволяет избежать записипрефикс / суффикс "изменяемый / неизменный" в начале / конце каждого имени метода.Следуя этой схеме, вы получите любой вспомогательный класс с именем «изменяемый / неизменяемый» (хорошо это или нет, но я оставлю этот вопрос открытым).

ПРОБЛЕМА ОДНОГО КЛАССА

Если мы хотим, чтобы эти методы были в одном классе (лучшее обслуживание), каков правильный «шаблон» именования?Шаблон, который я использовал в своем примере кода «asMutable / asImmutable» или вообще «изменяемый / неизменный», может быть несовместимым с более длинными именами методов.Есть ли другие варианты?

1 Ответ

0 голосов
/ 14 июня 2018

Редактирование на основе комментариев

Вы должны определенно реализовать изменяемые и неизменяемые классы отдельно.Имена методов могут быть похожими или разными, это не имеет значения, так как интерфейсы будут отличаться в любом случае.

Один класс

Стратегия изменчивости может быть упомянута в качестве дополнительного аргумента метода, например:

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);
    }
}
...