2014-12-23 2 views
-1

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

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

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

Мои варианты:

  1. сделать интерфейс принимать все возможные аргументы, а затем игнорировать их в реализации. Это не выполнимо, как в моем текущем коде, я вызываю ту же функцию с двумя разными аргументами, и поэтому мне нужно будет сделать две отдельные реализации этих функций, которые используют 2 отдельных аргумента и помещают оба из них в интерфейс (действительно уродливое решение)

  2. Внедрите интерфейс с помощью 2 методов, один из которых является doFilter(), другой является общим аргументом passArgument (Object ...), но это не отличается от вызова всех таких функций, как сейчас, но результат список, а затем вычислить max/min. Кроме того, я бы хотел, чтобы код «чистый» и передача непроверенных объектов выглядела как действительно уродливое решение

  3. Внедрить интерфейс как doFilter со всеми общими аргументами, а для остальных конкретных аргументов передать обратный вызов конструктору фильтр, который можно использовать для получения дополнительных параметров. Я первоначально пошел на это решение, но потом заметил, что одной из функций нужен параметр, который вычисляется внутри вызывающей функции, поэтому я либо делаю этот параметр полем в классе, и возвращают поле в обратном вызове, либо передаю новый обратный вызов, который каждый раз передает новое значение. Мне не нравится это последнее изменение, которое мне нужно будет сделать.

Итак, я прошу вас, есть ли парадигма/лучшая практика/дизайн, чтобы решить эту проблему?

Я беспокоюсь о не проблема? Сейчас класс не огромен, но по крайней мере половина его (если не больше) состоит из этих функций.

ответ

1

Еще один подход заключается в создании объекта «agument» - это будет POJO, который предназначен для хранения всей необходимой информации для всех методов и передачи только ее.

Каждый метод реализации получит этот объект и запросит нужное поле для получения соответствующего результата.

+0

К сожалению, это не устраняет проблему, вызванную limitToPreventChocksOnMiddleSCurve и limitToGrantMinimumDistanceVertically, которые вызывают одну и ту же функцию с двумя разными аргументами. В предложенном вами решении (которое на самом деле мало отличается от решения 2), мне нужно будет написать этот метод 2 раза после запроса одного поля и после запроса другой поданной. Я ошибаюсь? –

+0

@Makers_F Вы можете создать абстрактный класс, который реализует общую функциональность, и каждый реализующий конкретный класс использует его. – amit

0

Интерфейс должен иметь одну функцию без аргументов.

interface Filter 
{ 
    float doFilter(); 
} 

Различные реализации принимают свои значения при строительстве. Тогда вам не нужно беспокоиться о передаче аргументов.

+0

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

Смежные вопросы