Я знаю, что рефакторинг - это «изменение структуры программы таким образом, чтобы функциональность не изменилась». Я разговаривал с некоторыми ребятами, с которыми работаю над моим проектом на последнем курсе в университете, и был удивлен, что у них гораздо более широкий ( если не сказать лучшего слова) взгляд на рефакторинг.
Я считаю рефакторинг такими вещами, как извлечение методов и переименование классов. Они также предложили такие вещи, как изменение структур данных (например, Java LinkedList
на an ArrayList
), изменение алгоритмов (с использованием сортировки слиянием вместо пузырьковой) и даже переписывание больших фрагментов кода в качестве рефакторинга.
Я был совершенно уверен, что они ошибались, но я не мог объяснить причину, потому что то, что они предлагали, действительно изменило программу (и, предположительно, улучшило ее), не изменив ее поведения. Я прав и, что более важно, почему?
источник
Фаулер проводит четкую грань между изменениями в коде, которые влияют, и теми, которые не влияют на его поведение. Он называет те, которые этого не делают, «рефакторингом». Это является важным отличием, потому что если мы разделим нашу работу в рефакторинге и не рефакторинг кода модификации деятельности (Фаулер называет это «носить разные шляпы»), мы можем применить различные, нацеленные соответствующие методы.
Если мы проводим рефакторинг или модификацию кода с сохранением поведения:
Если мы делаем модификацию кода, изменяющую поведение:
Если мы упускаем из виду это различие, то наши ожидания относительно любой данной задачи модификации кода будут запутанными и сложными или, во всяком случае, более запутанными и более сложными, чем если бы мы это осознавали. Вот почему важно слово и его значение.
источник
Чтобы высказать свое мнение:
Небольшие инкрементальные изменения, которые оставляют код в лучшем состоянии, чем он был найден
Определенно да: «косметические» изменения, которые напрямую не связаны с функциями (т. Е. Не оплачиваются как запрос на изменение).
Определенно нет: перезапись больших кусков явно нарушает принцип «маленькие, инкрементальные». Рефакторинг часто используется как противоположность перезаписи: вместо того, чтобы делать это снова, улучшайте существующее.
Определенно возможно: замена структур данных и алгоритмов - это своего рода пограничный случай. Решающее различие здесь IMO - это маленькие шаги: будьте готовы к доставке, будьте готовы работать над другим делом.
Пример: представьте, что у вас есть модуль рандомизатора отчетов, работа которого замедляется из-за использования вектора. Вы профилировали, что вставки векторов являются узким местом, но, к сожалению, модуль во многих местах полагается на непрерывную память, поэтому при использовании списка все будет незаметно прерываться.
Переписывание означало бы выбросить модуль из здания, построение более качественное и быстрое, с нуля, просто взяв несколько частей из старого. Или написать новое ядро, а затем вставить его в существующий диалог.
Рефакторинг будет означать небольшие шаги по удалению арифметики указателя, так что переключатель. Возможно, вы даже создаете служебную функцию, обертывающую арифметику указателя, заменяя прямую манипуляцию указателем вызовами этой функции, затем переключайтесь на итератор, чтобы компилятор жаловался на места, где все еще используется арифметика указателя, затем переключитесь на a
list
, а затем удалите служебная функция.Идея состоит в том, что код становится хуже сам по себе. При исправлении ошибок и добавлении функций качество ухудшается небольшими шагами - значение переменной неуловимо меняется, функция получает дополнительный параметр, который нарушает изоляцию, цикл становится немного сложным и т. Д. Ничто из этого не является настоящей ошибкой, вы можете Не указывайте количество строк, которое делает цикл сложным, но вы ухудшаете удобочитаемость и обслуживание.
Точно так же изменение имени переменной или извлечение функции сами по себе не являются ощутимыми улучшениями. Но все вместе они борются с медленной эрозией.
Как стена из гальки, где каждый день падает на землю. И каждый день один прохожий поднимает его и кладет обратно.
источник
Принимая во внимание определение Мартина Фаулера,
... Думаю, вы однозначно правы.
Очевидно, что изменение алгоритма на что-то более быстрое - это не рефакторинг, потому что меняется внешнее поведение! (Опять же, если эффект никогда не будет заметен, возможно, вы все-таки могли бы назвать это рефакторингом - а также преждевременной оптимизацией. :-)
Это моя любимая мозоль; раздражает, когда люди используют этот термин небрежно - я даже встречал некоторых, кто случайно использовал рефакторинг практически для любых изменений или исправлений. Да, это модное и крутое модное слово и все такое, но нет ничего плохого в простых старых терминах, таких как изменение , переписывание или улучшение производительности . Мы должны использовать их, когда это уместно, и оставлять рефакторинг для случаев, когда вы действительно просто улучшаете внутреннюю структуру своего программного обеспечения. В команде разработчиков особенно важно иметь общий язык для точного обсуждения вашей работы.
источник
Если интерфейс к фрагменту кода меняется, я считаю, что это больше, чем рефакторинг.
Типичный случай рефакторинга:
Это означает, что термин «рефакторинг» относится к интерфейсу, который вы обсуждаете. т.е. вы могли бы реорганизовать код одного интерфейса, в то же время более широко изменяя код другого на более низком уровне (может быть, это различие вызывает путаницу между вами и вашими коллегами?)
источник
Думаю, вы правы, но спорить о значении слова не особо интересно или продуктивно.
источник
http://en.wikipedia.org/wiki/Code_refactoring
Я согласен с тем, что рефакторинг кода действительно включает нарушение существующего кода. Просто убедитесь, что у вас есть модульные тесты, чтобы не вводить никаких ошибок, а остальной код компилируется. Использование инструментов рефакторинга, таких как Resharper для C #, упрощает эту задачу!
источник
Я не согласен :
Вы уже знаете более точные термины, используемые для обозначения подмножеств рефакторинга, и да, это очень общий термин.
источник
Я думаю, что никому не может быть выгодно слишком строгое определение термина «рефакторинг». Граница между вашим восприятием и вашими коллегами размыта и может быть ближе к их или вашему мнению в зависимости от многих фактов. Поскольку он динамический, давайте попробуем определить его. Прежде всего определите границы системы или подсистемы, которую вы пытаетесь реорганизовать.
Если это метод, сохраните имя, входные аргументы, тип возвращаемого значения и, возможно, операторы бросания. Примените все изменения внутри метода, не изменяя его внешний вид.
Если вы реорганизуете класс, исправьте его общедоступный API и используя переменные переименования, методы извлечения и все другие доступные методы, чтобы сделать класс более читаемым и / или более производительным.
Если часть кода, который вы реорганизуете, является пакетом или модулем, выполните рефакторинг внутри него, возможно, переименовав классы, удалив, добавив интерфейсы, вставив / потянув код в суперклассы / подклассы.
источник
Рефакторинг = улучшение нефункциональных требований при сохранении неизменных функциональных.
Нефункциональные требования = модульность, тестируемость, ремонтопригодность, удобочитаемость, разделение проблем, лисковские принципы и так далее ...
источник