я в настоящее время есть класс с некоторым кодом, который в основном вызывает некоторые функции, а затем выполнить макс/мин на все результатыРеорганизовать код: от многих функций для взаимодействия системы
float limitOtherSide = limitImposedByPreviousVerticesOnOtherSide(other, pNewX, minimumDistance, pIsUpper);
float limitInterpolation = limitToPreventInterpolatedPointsTooClose(other, pNewX, temp, minimumDistance, pIsUpper);
float limitToPreventChocksOnMiddleSCurve = limitToAvoidChockesAlongAllTheSCurve(other, pNewX, temp, minimumDistance, playerWidth, pIsUpper);
float limitToGrantMinimumDistanceVertically = limitToAvoidChockesAlongAllTheSCurve(other, pNewX, temp, minimumDistance, 0, pIsUpper);
float limitOutOfScreenInterpolation = limitToPreventeForcedOutOfScreenNextOppositeVertex(other, pNewX, minimumDistance, pIsUpper);
float limitChocke = limitToAvoidChocke(other, pNewX, minimumDistance, pIsUpper);
if(pIsUpper) {
float max1 = Math.max(limitOtherSide, limitInterpolation);
float max2 = Math.max(limitToPreventChocksOnMiddleSCurve, limitOutOfScreenInterpolation);
float minimumY = Math.max(Math.max(max1, limitToGrantMinimumDistanceVertically), Math.max(max2, limitChocke));
newLowerY = MathUtilities.clamp(minimumY, 0.1f, 1);
newUpperY = 1.f;
} else {
float min1 = Math.min(limitOtherSide, limitInterpolation);
float min2 = Math.min(limitToPreventChocksOnMiddleSCurve, limitOutOfScreenInterpolation);
float maximumY = Math.min(Math.min(min1, limitToGrantMinimumDistanceVertically), Math.min(min2, limitChocke));
newUpperY = MathUtilities.clamp(maximumY, 0 , 0.9f);
newLowerY = 0.f;
}
float newY = (float) RANDOM.nextGaussian(newLowerY, newUpperY);
Я хотел бы реорганизовать его по нескольким причинам:
- функция является почти чистой и самодостаточной
- Я хотел бы, чтобы иметь возможность включать и выключать легко, который проверяет, чтобы выполнить (даже если это вопрос изменения исходного кода)
- Я хотел бы отделить предел проверки от остальной части кода класса, который является более общим о том, как создавать точки
- Я планирую добавить больше функций, которые будут загромождать класс еще
- Being в состоянии изменить только одну часть кода, чтобы добавить новую проверку, вместо того, чтобы конкатенировать еще больше Math.max и добавить переменные и т. д. в вызывающую функцию
Итак, я думал об изменении кода на что-то вроде
List<Filter> mFilters; //initialized in the constructor
[...]
if(pIsUpper) {
for(Filter f : mFilters) {
newLowerY = Math.max(newLowerY, f.doFilter(args..));
}
newLowerY = MathUtilities.clamp(newLowerY , 0.1f, 1);
newUpperY = 1.f;
} else {
for(Filter f : mFilters) {
newUpperY = Math.min(newUpperY , f.doFilter(args..));
}
newUpperY = MathUtilities.clamp(newUpperY , 0.1f, 1);
newLowerY = 0.f;
}
Дело в том, что я не знаю, как определить интерфейс. Как вы могли заметить, все функции имеют некоторые общие основные аргументы, но тогда они отличаются для некоторых из них.
Мои варианты:
сделать интерфейс принимать все возможные аргументы, а затем игнорировать их в реализации. Это не выполнимо, как в моем текущем коде, я вызываю ту же функцию с двумя разными аргументами, и поэтому мне нужно будет сделать две отдельные реализации этих функций, которые используют 2 отдельных аргумента и помещают оба из них в интерфейс (действительно уродливое решение)
Внедрите интерфейс с помощью 2 методов, один из которых является doFilter(), другой является общим аргументом passArgument (Object ...), но это не отличается от вызова всех таких функций, как сейчас, но результат список, а затем вычислить max/min. Кроме того, я бы хотел, чтобы код «чистый» и передача непроверенных объектов выглядела как действительно уродливое решение
Внедрить интерфейс как doFilter со всеми общими аргументами, а для остальных конкретных аргументов передать обратный вызов конструктору фильтр, который можно использовать для получения дополнительных параметров. Я первоначально пошел на это решение, но потом заметил, что одной из функций нужен параметр, который вычисляется внутри вызывающей функции, поэтому я либо делаю этот параметр полем в классе, и возвращают поле в обратном вызове, либо передаю новый обратный вызов, который каждый раз передает новое значение. Мне не нравится это последнее изменение, которое мне нужно будет сделать.
Итак, я прошу вас, есть ли парадигма/лучшая практика/дизайн, чтобы решить эту проблему?
Я беспокоюсь о не проблема? Сейчас класс не огромен, но по крайней мере половина его (если не больше) состоит из этих функций.
К сожалению, это не устраняет проблему, вызванную limitToPreventChocksOnMiddleSCurve и limitToGrantMinimumDistanceVertically, которые вызывают одну и ту же функцию с двумя разными аргументами. В предложенном вами решении (которое на самом деле мало отличается от решения 2), мне нужно будет написать этот метод 2 раза после запроса одного поля и после запроса другой поданной. Я ошибаюсь? –
@Makers_F Вы можете создать абстрактный класс, который реализует общую функциональность, и каждый реализующий конкретный класс использует его. – amit