Пример — компонентная архитектура, со связями, основанными на событиях.
Код компонентов относительно (системы) не сложный, однако при наличии множества получателей или генераторов одинаковых событий структура runtime-связей будет далеко не тривиальной.
Как правило, интеграционные тесты в этих случаях покрывают только наиболее частые и значимые ветки.
Иногда код написан таким образом, что число веток растет по экспоненте.
В этом случае тесты не помогут — такое число веток ни один тест не покроет, либо тест окажется сравним по сложности с самим кодом.
В этих случаях, как правило, необходимо пересматривать код на предмет упрощения логики и разбиения на зап. части, которые можно будет тестировать независимо.
Да и вообще, если писать код, ориентируясь на его тестирование, он получается много проще… и писать его на порядок сложнее.
Не надоело. Предпочитаю полную ясность.
Если Вы говорите про частный случай — лучше укажите, что бывают исключения, и в каких случаях.
Доступ к внутренним поля объекта источника делается через захват this
Описал альтернативный вариант в комментарии ниже.
проблемы видимости решаются средствами языка
В языке может не оказаться таких средств. В этом случае используем ограниченный интерфейс, передаваемый в конструкторе — не обязательно весь this, часто им оказывается более узкий интерфейс или вообще адаптер.
Хорошие примеры подобных рефакторингов можно найти в книге «Чистый код» (Clean code).
Вы не согласны, что развернутое описание более полезно?
Конечно.
continue — в начале или в конце цикла, в более редких случаях допустимо в середине. Не более одного на цикл.
Группы break по разным условиям собираем вначале или в конце цикла.
Любые более сложные комбинации лучше выносить в отдельный метод (к return'ам это тоже применимо).
Именно так. Причем оптимизацию можно делать только 1) проверяя под все целевые архитектуры 2) проверяя под всеми используемыми компиляторами с нужными параметрами сборки.
Да, выносить в отдельный класс. Лучше всего — с максимально ограниченной областью видимости.
Если нужно добираться до переменных экземпляра, внутри которого все это было — передайте их в конструкторе.
Если же их нужно менять… Можно передать в конструкторе простой объект с set-методами. Но если их слишком много… необходимо рассмотреть этот частный случай детально, я не готов решать эту проблему в абстрактном случае.
Связка строки с именем — скользкая дорожка динамического программирования.
Может в разы уменьшить количество сопровождающего кода, а также автоматически поддерживать изменения, но увеличивает сложность отладки в N раз.
Предпочитаю рефакторить до цепочки if-elseif, вынесенной в отдельный метод, осуществляющей преобразование в нужный мне объект, и только после этого заменять статическую связку if-elseif на динамический reflection.
Получаем относительную безопасность и локализацию подхода с одной стороны, и плюшки минимизации поддержки кода — с другой.
Код с ретурнами должен соответствовать одному из следующих случаев:
1) Иметь строгую линейную структуру:
if (...) {
...
return;
}
if (...) {
...
return;
}
if (...) {
...
return;
}
...
2) Если метод состоит из ровно одного цикла — обеспечивать выход из цикла по заданному условию, стоящему либо в начале, либо в конце цикла (не в середине!)
3) return во всех ветках оператора switch-case (включая default, даже если он не написан явно!).
Код компонентов относительно (системы) не сложный, однако при наличии множества получателей или генераторов одинаковых событий структура runtime-связей будет далеко не тривиальной.
Как правило, интеграционные тесты в этих случаях покрывают только наиболее частые и значимые ветки.
В этом случае тесты не помогут — такое число веток ни один тест не покроет, либо тест окажется сравним по сложности с самим кодом.
В этих случаях, как правило, необходимо пересматривать код на предмет упрощения логики и разбиения на зап. части, которые можно будет тестировать независимо.
Да и вообще, если писать код, ориентируясь на его тестирование, он получается много проще… и писать его на порядок сложнее.
Если Вы говорите про частный случай — лучше укажите, что бывают исключения, и в каких случаях.
Описал альтернативный вариант в комментарии ниже.
В языке может не оказаться таких средств. В этом случае используем ограниченный интерфейс, передаваемый в конструкторе — не обязательно весь this, часто им оказывается более узкий интерфейс или вообще адаптер.
Хорошие примеры подобных рефакторингов можно найти в книге «Чистый код» (Clean code).
Вы не согласны, что развернутое описание более полезно?
continue — в начале или в конце цикла, в более редких случаях допустимо в середине. Не более одного на цикл.
Группы break по разным условиям собираем вначале или в конце цикла.
Любые более сложные комбинации лучше выносить в отдельный метод (к return'ам это тоже применимо).
Спасибо за теплые слова.
Иначе будет нахватывание рецептов по верхушкам без понимания сути.
Полное отсутствие связей — это неиспользуемый код )
Не всегда это в принципе нужно — это два.
И вообще, прежде чем подумать — подумай :-)
Если нужно добираться до переменных экземпляра, внутри которого все это было — передайте их в конструкторе.
Если же их нужно менять… Можно передать в конструкторе простой объект с set-методами. Но если их слишком много… необходимо рассмотреть этот частный случай детально, я не готов решать эту проблему в абстрактном случае.
Может в разы уменьшить количество сопровождающего кода, а также автоматически поддерживать изменения, но увеличивает сложность отладки в N раз.
Предпочитаю рефакторить до цепочки if-elseif, вынесенной в отдельный метод, осуществляющей преобразование в нужный мне объект, и только после этого заменять статическую связку if-elseif на динамический reflection.
Получаем относительную безопасность и локализацию подхода с одной стороны, и плюшки минимизации поддержки кода — с другой.
1) Иметь строгую линейную структуру:
2) Если метод состоит из ровно одного цикла — обеспечивать выход из цикла по заданному условию, стоящему либо в начале, либо в конце цикла (не в середине!)
3) return во всех ветках оператора switch-case (включая default, даже если он не написан явно!).