Рефакторинг прочь меченая петля

голоса
18

После того, как я был убежден , что меченый брейки / продолжается в общей сложности «Ноно» над здесь , мне нужна помощь , чтобы удалить ярлык из моего кода.

У меня есть матрица квадратная и вектор, который имеет ту же длину. Вектор уже некоторые значения в нем в зависимости от значений в матрице вектор изменяется в цикле.

Я надеюсь, что код-фрагмент в основном понятно ...

vectorLoop:
for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) ) continue vectorLoop;

    matrixLoop:
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue matrixLoop;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) continue vectorLoop;
    }
    setValueInVector( v, idx );
}     

Пожалуйста, убедите меня, что есть более читаемый / лучший вариант без этикеток.

Задан 19/08/2008 в 08:42
источник пользователем
На других языках...                            


12 ответов

голоса
33

Глядя на решения, представленные до сих пор:

  • Все они выглядят менее читаемыми, чем оригинал, в том, что они включают расходы больше коды на механизме коды, а не на самом алгоритме

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

  • Некоторые приходят с исполнения наказания в виде работает тот же тест дважды, что не всегда может быть тривиальным. Альтернатива, которая хранит и обойдя булевы, который получает некрасиво.

  • Рефакторинг соответствующей части кода в метод не является эффективным не-оп: она перестраивается, как код выкладывается в файле, но не имеет никакого влияния на то, как он выполняется.

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

Ответил 19/08/2008 в 11:14
источник пользователем

голоса
1

Я думаю, что меченые петли настолько редко, что вы можете выбрать любой метод мечения работает для вас - то, что у вас там делает ваши намерения с продолжает совершенно ясно.


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

То, что я представлял себе был совсем другой кусок кода - поставить конкретный пример, я могу видеть, что это гораздо чище, чем я думал.

Мои извинения за недоразумение.

Ответил 20/08/2008 в 05:26
источник пользователем

голоса
1

Этот вопрос был не об оптимизации алгоритма - но все равно спасибо ;-)

В то время я писал это, я считал, мечеными продолжать как читаемое решение.

SO спросил я вопрос о конвенции (имеющей метку во всех колпачков или нет) для меток в Java.

В принципе каждый ответ сказал мне «не использовать их - всегда есть лучший способ реорганизовать!». Так что я отвечал на этот вопрос, чтобы попросить более читаемым (и, следовательно, лучше?) Решения.

До сих пор я не являюсь полностью убедил альтернативы, представленные до сих пор.

Пожалуйста, не поймите меня неправильно. Этикетки злы большая часть времени.

Но в моем случае, условные тесты очень просты и алгоритм берутся из математической бумаги и, следовательно, весьма вероятно, не изменится в ближайшем будущем. Поэтому я предпочитаю иметь все соответствующие части видны сразу, вместо того, чтобы перейти к другому методу с именем что-то вроде checkMatrixAtRow (х).

Особенно в более сложных математических алгоритмах, я считаю, это довольно трудно найти «хорошие» функцию-имена - но я думаю, что это еще один вопрос

Ответил 19/08/2008 в 17:28
источник пользователем

голоса
1
Некоторые приходят с исполнения наказания в виде работает тот же тест дважды, что не всегда может быть тривиальным. Альтернатива, которая хранит и обойдя булевы, который получает некрасиво.
Штраф производительности является незначительным. Однако я согласен, что работает тест дважды не хорошее решение.

Я считаю, что вопрос заключается в том, чтобы удалить ярлыки, а не как оптимизировать алгоритм. Мне казалось, что оригинальный плакат не знал о том, как использовать «продолжить» и «перерыв» ключевые слова без этикетки, но, конечно, мои предположения могут быть неправильными.

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

При этом, делая тот же тест дважды не является оптимальным в теории.

EDIT: На второй мысли, пример на самом деле не попало использование этикеток. Я согласен , что «Гото нет-нет» , но не из - за такого кода. Использование меток здесь фактически не влияет на читаемость кода существенным образом. Конечно, они не являются обязательными и могут быть легко опущены, но не используют их просто потому , что « с помощью метки плохо» не является хорошим аргументом в этом случае. В конце концов, удаление метки не делает код гораздо легче читать, а другие уже прокомментировали.

Ответил 19/08/2008 в 13:15
источник пользователем

голоса
1

@ Николас

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

У меня есть другая точка зрения: некоторые из них сломаны, потому что это трудно понять поведение исходного алгоритма.

Я понимаю, что это субъективно, но у меня нет никаких проблем с чтением оригинального алгоритма. Это короче и яснее, чем предлагаемые замены.

Что все рефакторинга в этой теме сделать эмулировать поведение этикетки с использованием других функций языка - как если бы вы портирования кода на языке, который не имел этикетки.

Ответил 19/08/2008 в 12:28
источник пользователем

голоса
1

От чтения кода.

  • Я заметил ваше устранение недопустимого вектора позиции в conditionAtVectorPosition затем удалить недопустимые строки в anotherConditionAtVector.
  • Похоже, что проверка строк на anotherConditionAtVector является излишним, так как независимо от значения IDX есть, anotherConditionAtVector зависит только от индекса строки (предполагая, что anotherConditionAtVector не имеет побочных эффектов).

Таким образом, вы можете сделать это:

  • Получить действительные позиции первого с помощью conditionAtVectorPosition (это действительные столбцы).
  • Затем получить действительные строки с помощью anotherConditionAtVector.
  • Наконец, используйте conditionAtMatrixRowCol используя действительные столбцы и строки.

Надеюсь, это поможет.

Ответил 19/08/2008 в 10:09
источник пользователем

голоса
1

@Patrick вы предполагаете, вызывая setValueInVector (V, IDX); в конце второго цикла ОК. Если код должен быть идентичным, по логике, он должен быть переписан somethng так:

для (INT IDX = 0; IDX 
Ответил 19/08/2008 в 08:56
источник пользователем

голоса
1

Легко, мой хороший человек.

for( int idx = 0; idx < vectorLength; idx++) {
  if( conditionAtVectorPosition( v, idx ) ) continue;

  for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
    if( anotherConditionAtVector( v, rowIdx ) ) continue;
    if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) break;
  }
  if( !conditionAtMatrixRowCol( m, rowIdx, idx ) )
    setValueInVector( v, idx );
}

EDIT: Совершенно верно вы Андерс. Я редактировал мое решение, чтобы принять во внимание, как хорошо.

Ответил 19/08/2008 в 08:45
источник пользователем

голоса
0

@ Sadie :

Все они выглядят менее читаемыми, чем оригинал, в том, что они включают расходы больше коды на механизме коды, а не на самом алгоритме

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

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

У меня есть другая точка зрения: некоторые из них сломаны, потому что это трудно понять поведение исходного алгоритма.

Некоторые приходят с исполнения наказания в виде работает тот же тест дважды, что не всегда может быть тривиальным. Альтернатива, которая хранит и обойдя булевы, который получает некрасиво.

Штраф производительности является незначительным. Однако я согласен, что работает тест дважды не хорошее решение.

Рефакторинг соответствующей части кода в метод не является эффективным не-оп: она перестраивается, как код выкладывается в файле, но не имеет никакого влияния на то, как он выполняется.

Я не вижу смысла. Да, это не меняет поведение, как ... рефакторинга?

Конечно, есть случаи, когда метки используются неправильно и должны быть переработаны в стороне. Я просто не думаю, что это следует рассматривать как некоторые нерушимое правило.

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

Ответил 19/08/2008 в 12:01
источник пользователем

голоса
0

Я не слишком уверен, чтобы понять первый продолжить. Я хотел бы скопировать Gishu и написать что-то вроде (извиняется, если есть какая-то ошибка):

for( int idx = 0; idx < vectorLength; idx++) {
    if( !conditionAtVectorPosition( v, idx ) && CheckedEntireMatrix(v))
        setValueInVector( v, idx );
}

inline bool CheckedEntireMatrix(Vector v) {
    for(rowIdx = 0; rowIdx < n; rowIdx++)
        if ( !anotherConditionAtVector(v,rowIdx) && conditionAtMatrixRowCol(m,rowIdx,idx) ) 
            return false;
    return true;
}
Ответил 19/08/2008 в 09:50
источник пользователем

голоса
0

Gishu имеет право идея:

for( int idx = 0; idx < vectorLength; idx++) {
    if (!conditionAtVectorPosition( v, idx ) 
        && checkedRow(v, idx))
         setValueInVector( v, idx );
}

private boolean checkedRow(Vector v, int idx) {
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }  
    return true;
}
Ответил 19/08/2008 в 09:46
источник пользователем

голоса
0

Работает ли это для вас? Я извлек внутренний цикл в методе CheckedEntireMatrix (вы можете назвать это лучше, чем у меня) - Кроме того, моя ява немного ржавая .. но я думаю, что он получает сообщение через

for( int idx = 0; idx < vectorLength; idx++) {
    if( conditionAtVectorPosition( v, idx ) 
    || !CheckedEntireMatrix(v)) continue;

    setValueInVector( v, idx );
}

private bool CheckedEntireMatrix(Vector v)
{
    for( rowIdx = 0; rowIdx < n; rowIdx++ ) {
        if( anotherConditionAtVector( v, rowIdx ) ) continue;
        if( conditionAtMatrixRowCol( m, rowIdx, idx ) ) return false;
    }   
    return true;
}
Ответил 19/08/2008 в 08:56
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more