Меня зовут Евгений Шумилов, я директор компании «1С-ИжТиСи». В IT-сфере с 1990 года. В течение 20 лет активно разрабатываю информационные системы для автоматизации деятельности предприятий. Участвовал в качестве разработчика и архитектора в создании тиражных решений с нуля и во внедрениях существующих систем различных масштабов и всевозможных сферах. Создавал программные продукты на разных языках и СУБД.
Последние 10 лет основная специализация нашей компании – автоматический анализ, генерация и модификация программ на платформе «1С:Предприятие».
Например, мы создаем инструменты для:
- Автоматизированного обновления конфигураций;
- Автоматического тестирования;
- Автоматического перевода решений на новые платформы;
- А также ускорения кастомизации решений.
В статье я расскажу про одну очень интересную технологию – рефакторинг. О том, что это такое и для чего нужен. Как я к нему пришел, почему полюбил и как применяю его на своей практике.
Также мы с вами рассмотрим признаки хорошего и красивого кода, разберемся, когда стоит заниматься рефакторингом, какие могут возникнуть проблемы при его применении и как их избежать.
Что такое рефакторинг и для чего он нужен
Итак, что же такое рефакторинг? Грубо говоря, это переписывание программы для ее внутреннего улучшения.
Сам процесс существует довольно давно. Термин ввел Уильям Опдайк в одной из своих статей в 1993 году. В настоящее время многие IT-команды, включая нашу компанию, применяют рефакторинг и извлекают из этой технологии дополнительные выгоды.
Для начала рассмотрим простой пример. Лев Толстой переписывал «Войну и мир» восемь раз. Отдельные эпизоды – более двадцати шести раз. Конечно, этим занимались все писатели и до, и после него.
Все творческие люди переписывают свои книги, стихи, картины. Они занимаются постоянным улучшением, пытаются приблизить свое творение к совершенству.
Рефакторинг – это процесс достижения прекрасного.
Любую мысль в коде или в художественном произведении можно изложить по-разному. Суть рефакторинга – это улучшение формы изложения своей мысли. Информация, которую вы хотите передать, или результат, которого хотите достичь, остаются теми же самыми. При этом форма подачи мысли становится проще, понятнее, лучше.
Взять того же Льва Толстого. Я его прочитал с интересом, мне он очень нравится. При этом читать его откровенно трудно, у него очень сложный слог. А вот, например, Чехов или Булгаков читаются значительно проще, на одном дыхании. Речь просто льется с их страниц! Текст гораздо приятнее и красивее.
Кстати, этот доклад – тоже результат рефакторинга. Изначально он был больше 3 часов. Мы его переработали, чтобы вам было вкуснее слушать.
Есть такое понятие – энтропия. В физике и математике это мера хаоса. В 2013 году здесь же, на Инфостарте, выступал мой хороший знакомый, один из моих учителей Дмитрий Малюгин из славной компании «Кинт». Он в своем шикарном докладе рассказывал про энтропию метаданных и различные методы борьбы с ней.
Запись этого выступления есть на сайте Инфостарта, вы можете ее посмотреть. Сегодня я более узко расскажу про один из методов уменьшения хаоса.
Итак, второй закон термодинамики гласит, что в замкнутой системе уровень хаоса возрастает или как минимум остается постоянным. Что это значит для нас? Когда мы написали программу, уровень хаоса в ней зафиксировался. Как только мы что-то меняем в ней, хаос уверенно начинает расти. И чем больше мы дорабатываем программу, чем больше людей участвует в проекте, тем больше беспорядка, «грязи» в разрабатываемом продукте. И тем сложнее будет поддерживать и модифицировать систему в будущем, разрабатывать новый полезный функционал.
Таким образом, рефакторинг – это метод борьбы с бардаком, делающий проект и в целом мир прекраснее.
В классическом понимании рефакторинг – это улучшение кода без изменения функциональности продукта. Лично я считаю чуть по-другому.
Даже если при начале рефакторинга мы хотим оставить прежний функционал, в процессе поиска более изящного решения можно получить какую-то новую клевую фичу или функциональность. Их сможет применять пользователь при работе в вашей программе. Или когда вы возьметесь за новый проект, у вас появится замечательный шанс повторно использовать тот же обобщенный функционал
Если вы регулярно пытаетесь добиться идеала в том, что делаете, у вас обязательно родятся новые уникальные, полезные методы и технологии.
Масштаб проблемы
Лично я постоянно переписываю свои программы, совершенствую их как внутри, так и снаружи. Очень хочу, чтобы код, с которым я работаю, выглядел круто.
Когда я узнал, что такое рефакторинг, понял эту технологию, начал активно ее применять, тут же влюбился в него.
Обожаю, когда то, что я творю, красиво и аккуратно, радует глаз. Если вижу, что где-то можно сделать лучше, возникает острое желание переписать этот кусок кода.
На рабочем столе может быть бардак, в голове может быть бардак. В коде всегда должно быть чисто и красиво! Всегда!
В свое время у меня появилась идея фикс добиться минимизации объема используемого кода. В ходе этих работ я применил гипертрофированный подход, в результате которого смог создавать программы, делающие то, что требуется, при этом содержащие ноль строк кода.
Как это вообще возможно? Есть различные методы и технологии для достижения этой цели. Сейчас я не буду на них останавливаться.
Для примера расскажу только об одном методе. В нашей компании мы часто используем следующую технологию. Перед запуском программы или модуля анализируем исходный код и, исходя из названий и каких-то дополнительных управляющих конструкций, генерируем дополнительный код, который в будущем будет выполняться.
Теперь давайте разберемся, что такое хорошо и что такое плохо. И как сделать наш код гораздо лучше.
Самая простая и самая серьезная ошибка при программировании – несоблюдение стандартов разработки. В разных командах и проектах они могут быть совершенно отличные друг от друга. Так или иначе, стандарты должны быть. Обязательно! При любой разработке и тем более коллективной.
У кого есть свой стандарт разработки? А кто всегда его придерживается? А кто постоянно соблюдает стандарты 1С? А кто знает, что они вообще существуют и в них более 200 страниц текста?
Бывают случаи, программист пишет для себя временный код, который никто не будет читать. Если разработчику пофиг, что он делает, то может писать абы как. Лично мне так делать противно.
Один из самых наиважнейших факторов, влияющих на трудность модификации программной системы, это размер кодовой базы. Чем меньше кода, тем лучше.
Вернемся к тому же Льву Толстому. Он без сомнения красавчик. Но кто прочитал полностью все четыре тома «Войны и мир»? Кто сделал это с первого раза? А кто при подготовке к экзамену прочитал ее же, но в кратком изложении? Разумеется, прочитать пару страниц сокращенного текста гораздо проще, чем четыре огромные книги.
В кратком содержании, конечно много важного и вкусного пропущено, но общий смысл сохранился. При этом литературное произведение и код – разные вещи. В одном случае нормально использовать метафоры и красивые описания. В коде лучше все-таки этого избегать. Минимум «воды» и максимум смысла. Я думаю, что вы, как и я, не способы прочитать десятки тысяч строк кода, понять, что там происходит, запомнить с первого раза, а потом оперативно с этим работать. При этом думаю, логично, что чем меньше, тем проще прочитать, запомнить и понять. Это как раз тот случай, когда размер имеет значение.
Мы проанализировали несколько конфигураций. Есть функции, где больше десяти тысяч строк кода. Их писали гении. Но лично мне очень сложно понять такие функции. Если вы сходу можете понять такой код, то вы тоже гениальны! Я реально вам завидую!
Еще один пример, хорошо иллюстрирующий, что чем больше, тем сложнее, – запросы на несколько тысяч строк, пусть даже склеиваемые в результате выполнения нескольких функций. Вроде компактно, но если посмотреть на результирующий запрос, попытаться его доработать или исправить ошибку, начинается интересный процесс. Большой запрос начинаем разбивать на маленькие и последовательно смотреть, что же там происходит. Постепенно доходя до полного.
Да, пока это отраслевой стандарт – большие запросы. По-другому пока не получается. Это прекрасная возможность придумать, как делать по-другому. Зачем? По фану. Из лени. И чтобы спасти пару-тройку жизней программистов.
В нашей компании мы регулярно сталкиваемся с конфигурациями, где очень много кода. И когда делаем обновление таких конфигураций, даже у наших роботов «кипят мозги».
В идеальной программе объем кода должен стремиться к нулю. В идеале должно быть только техническое задание. Или описание того, что нужно получить на выходе.
Когда компьютеры начнут понимать задачу, сформулированную на естественном языке, произойдет технологическая революция. Именно такими технологиями, как рефакторинг, к этому можно приблизиться.
Думаю, многие из вас знакомы с пакетами программ типа «Mathematica». Программа просто потрясающая. Пишешь уравнение или какую-либо математическую задачу на классическом математическом языке – и программа все сама понимает и решает. Как она это делает, пользователю, по сути, не важно. Мы сформулировали задачу и получили результат. При этом система может не только дать правильный ответ, но и подробное объяснение решения.
Еще один пример от тех же разработчиков, что и «Mathematica» – система «Wolfram|Alpha». Там вообще все гениально. В ней можно задать вопрос из 3 слов, какой цвет чаще всего используется во флагах стран мира, и система выдаст ответ. То есть программа фактически без кода делает то, что нам необходимо. Мы лишь формулируем задачу или вопрос и получаем результат.
Еще один великолепный пример на эту тему – когнитивная система «IBM Watson». Она в 2011 году выиграла у сильнейших игроков в американскую версию «Своей игры». Сейчас «IBM Watson» используется в медицине для лечения рака. Она диагностирует лучше врачей-экспертов и предлагает пациенту индивидуальное лечение.
Следующий признак хорошего кода – названия переменных и функций. Они должна быть минимальны и понятны.
Очень простой пример – что такое собачка?
Для одного человека это замок на молнии куртки, для другого – символ в адресе почты, для третьего – животное. Причем каждый представляет себе собачку по-разному. Для брутального мужика это алабай, а для девочки – шпиц.
Одна из причин, почему я в свое время перешел с других сред на платформу 1С – мы пишем на родном языке, и все предельно понятно. В других языках программирования при переводе какой-то смысл может теряться.
Следующий пункт – отсутствие комментариев. Лично для меня это один из основных критериев того, что код хороший.
Если код требуется комментировать, это плохой код. Он может быть очень сложным для понимания, при этом обязан быть самодокументируемым и говорить сам за себя.
Следующая очень важная задача – писать грамотно.
Существует программный продукт «Автоматизированная проверка конфигураций». Наша компания разрабатывает его для фирмы «1С». Он предназначен для выполнения проверки конфигураций на соответствие стандартам. В том числе в него встроена проверка орфографии.
В идеале ее необходимо запускать перед выпуском каждого релиза. При разработке типовых конфигураций в 1С это один из обязательных шагов производственного процесса.
Другой важный момент – функции и отдельные их части не должны быть копипастом друг друга.
Я прекрасно понимаю, это действительно прикольно. Но представьте, через год вы решите доработать проект. Тут поправите, там поправите и где-то обязательно забудете. А потом – как неожиданно! – где-то что-то сломается. И как обычно в самый неподходящий момент.
Если есть повторяющиеся действия, правильнее выносить их в отдельную функцию.
Кроме этого, в одной процедуре лучше избегать смешивания выполнения различных малосвязанных вещей. Например, функция устанавливает видимость элементов формы, и в ней же проводится загрузка данных в какую-то таблицу значений. Лично для меня это моветон.
Идем дальше. Еще один признак хорошего кода – параметров в функциях и процедурах должно быть минимум.
Кто-то получает удовольствие, переписывая свой функционал, когда у библиотечной функции добавился новый обязательный параметр? А остальные? Не получали удовольствие, но все равно делали?
Так вот, в идеале параметры должны отсутствовать. Безупречная функция сама должна определять контекст своей работы во время выполнения и извлекать из него необходимые параметры.
Следующий пункт – вложенность операторов и конструкций. Большой вложенности лучше избегать. Одного-двух уровней достаточно, чтобы не перегружать код.
Есть еще много признаков хорошего кода. Пока остановимся на этих основных пунктах.
Когда стоит заниматься рефакторингом
Давайте теперь разберемся, когда вообще стоит, а когда не стоит заниматься рефакторингом.
Перфекционизм – прекрасная вещь. При этом в промышленном производстве программных продуктов он полезен не всегда. Например, когда пишешь программку для изучения какой-то технологии, для себя. Написал – забыл. Или олимпиадная задача по программированию. Или если программа не будет развиваться. Тогда рефакторингом заниматься особого смысла нет.
А если программа будет жить долго, в ней будет появляться новый функционал, будут регулярно выпускаться новые релизы, то чем раньше написано хорошо, тем лучше. В идеале надо сразу писать красивый код.
Еще один нюанс. В разработке всегда есть бюджет, есть сроки выпуска релизов, того или иного функционала. И заниматься рефакторингом заказчик или руководитель проекта просто так не даст. Постоянно будет стоять над душой, требовать, чтобы все было готово «вчера».
Все ведь писали программу «вчера»? Отлично вас понимаю, я и писал, и стоял «над душой».
При этом если и бюджет, и сроки позволяют, рефакторингом заниматься можно, а в некоторых случаях просто необходимо.
Еще один важный момент. Бывает, добавили крутую фичу, а в другом месте все сломалось. В данном случае есть вариант, что энтропия очень высока, и, возможно, настал тот момент, когда стоит все полностью переписать, чтобы навести порядок. Любой код до тех пор, пока он существует, можно сделать лучше. Иногда это долго и дорого, но возможно всегда.
Следующий пункт. Можно написать код, а потом заниматься рефакторингом. А можно сразу писать хорошо. Естественно, делать хорошо сразу – правильнее, быстрее и дешевле.
При этом если регулярно заниматься рефакторингом, со временем какие-то вещи начинаешь делать сразу правильно, не задумываясь, пишешь более лаконично и красиво.
Вспомните, как вы учились управлять автомобилем. Сначала вы жутко волновались, дрожали, не понимали, что, куда и как. А сейчас можете одной рукой держать телефон и разговаривать, другой – красить губы, а коленками – рулить. И при этом еще обсуждать того «хорошего» человека в соседнем ряду, который вас только что подрезал.
Если вы будете постоянно чему-то учиться, в результате вы будете делать это на автомате. В любой сфере деятельности.
Например, у нас в компании мы сразу учим стажеров рефакторингу. И не допускаем к каким-то реальным задачам до тех пор, пока ученик допускает нарушение стандартов.
В университете нас учат писать программы, составлять алгоритмы, но делать это правильно не учат. В большинстве случаев преподаватели даже не смотрят исходный код. Результат работы на экране устраивает – сойдет.
Чем раньше человек осознает, какими методами можно сделать свой же код лучше, тем раньше он начнет писать более красиво.
Итак, заниматься рефакторингом очень важно. Когда его применять, зависит от вас и от проекта, в котором вы участвуете.
Как избежать проблем рефакторинга
Сейчас мы перейдем к следующей важной теме – как избежать проблем, которые могут возникнуть при выполнении рефакторинга, и как рефакторинг улучшает качество разрабатываемых программ и развивает ваши навыки.
На текущий момент рефакторинг – это одна из методологий экстремального программирования. В него входят разные «вкусняшки». Далее мы поговорим о них, и как они взаимосвязаны.
Вы могли подумать, что с рефакторингом связаны определенные риски. Да, безусловно, вы абсолютно правы. К слову, как и с любой другой технологией.
Как и при любой другой модификации программы, при рефакторинге крайне желательно иметь максимальное покрытие кода автоматическими тестами. После внесения изменений важно убедится, что все работает как раньше и корректно. Именно поэтому если этот вопрос у вас открыт, пора подумать о том, чтобы начать внедрять у себя системы автоматического тестирования.
Например, мы используем один из своих программных продуктов. Он позволяет проводить автоматическое тестирование и дает гарантию безопасности проведения рефакторинга и других работ с конфигурацией.
Следующий важный момент. Представьте, вы написали какой-то код и вернулись к нему спустя год или пять. Смотрите на него и думаете: «Кто это сделал? Оторвать бы автору руки!»
У всех такое было? Я очень вас понимаю, я сам себя часто по рукам бил.
Это происходит потому, что мы все развиваемся, становимся круче. И со временем наши прошлые творения начинают нас немного огорчать. При этом можно же было сразу увидеть косяки, но мы их часто не видим, потому что любим продукт своего творчества. Для рефакторинга необходимо уметь включать критическое мышление, чтобы смотреть под другими углами. Сразу, а не через насколько лет.
Двигаемся дальше. Рефакторинг очень полезен как способ повышения квалификации.
В рамках самообучения полезно взять какой-то свой, хотя можно и чужой, проект или модуль и максимально его упростить, сделать более универсально и красиво. Проводите рефакторинг до упора. А когда зашли в тупики, кажется, вот он, идеал, покажите код другому специалисту, и, думаю, он даст вам еще парочку идей.
В результате этого процесса у вас точно возникнут новые интересные методы, которые дальше будут применяться вами автоматически при создании нового функционала.
Еще одна методология экстремального программирования – это защита кода. Она заключается в следующем. Один программист разработал какую-либо интересную и полезную вещь, потом на собрании демонстрирует ее другим участникам команды. Каждый из них высказывает свое мнение относительно данного функционала. В результате могут быть найдены различные явные и неявные ошибки, получены важные замечания и совместные идеи о том, что и как можно делать лучше. Группа людей заметит то, что может проглядеть один.
Причем защита кода полезна и тому, кто писал код, и тем, кто принимает участие в обсуждении, и конечно это полезно для всего проекта. Происходит обмен опытом, «прокачка» навыков всех участников, развиваются коммуникации внутри группы. Также появляется коллективное владение кодом. В будущем больше людей смогут его дорабатывать. Критично важно – идет конструктивное обсуждение кода, а не личности, его создавшей.
В некоторых командах принято, что все новое попадет в релиз только после защиты кода. Защитили – принимаем. В противном случае переделываем и снова защищаем.
Другая методология экстремального программирования – парное программирование. Это почти та же самая защита кода, но в реальном времени.
Один разработчик пишет, а другой в то же самое время смотрит написанный код, дает свои рекомендации, указывает на ошибки и неточности, говорит, что и как можно сделать лучше.
В современном мире и тем более в сфере 1С мало кто это практикует, так как метод считается довольно дорогим. Однако по факту он окупает себя, особенно при обучении и интеграции в команду нового специалиста. Чем раньше новичок участвуют в таком «шоу», тем быстрее приобретает нужные полезные навыки и включается в команду.
Выгоды рефакторинга
Итак, рефакторинг сам по себе штука чрезвычайно полезная. Конечно, с ним связаны определенные риски. При этом если вы правильно подойдете к его применению, вы получаете огромную выгоду и всякие дополнительные «плюшки». У вас повышается качество программ, уменьшается количество ошибок сейчас и в будущем, снижаются финансовые затраты на поддержку и время реализации нового функционала.
Все начинается с малого
В заключении расскажу одну реальную историю.
В восьмидесятые годы прошлого века в Нью-Йорке была дикая преступность. Как же поступили власти Нью-Йорка? Они начали бороться с мелкими правонарушениями. Запретили гадить в метро, рисовать граффити на вагонах, боролись с безбилетниками. Арестовывали каждого, кто пьянствовал и буянил в общественных местах. В итоге к концу 1990-х Нью-Йорк стал самым безопасным городом США. Этот социальный эффект получил название «теория разбитых окон».
К чему я это веду? Порядок повсюду начинается с порядка малого. Если вы «не мусорите» в названиях переменных, в функциях, соблюдаете элементарные правила орфографии и прочие стандарты, не балуетесь копипастом и дикой вложенностью, потом эта привычка писать красиво распространится на весь код, на всю программу.
Заключение
Чем чаще вы занимаетесь рефакторингом, тем более хороший код пишете. В итоге вы значительно повышаете качество своих программ.
Любите то, чем занимаетесь! Делайте мир лучше! Пишите красивый код!
****************
Данная статья написана по итогам доклада (видео), прочитанного на конференции INFOSTART EVENT 2017 COMMUNITY.