Что такое рефакторинг и в чем его цели

30.10.18

Разработка - Рефакторинг и качество кода

Что такое рефакторинг, и в каких случаях им стоит заниматься? Евгений Шумилов дает ответы на эти вопросы, а также рассказывает о признаках хорошего и плохого кода. Кроме того, в статье приведены основные проблемы рефакторинга и способы их решения.

Меня зовут Евгений Шумилов, я директор компании «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.

рефакторинг

См. также

Когда понадобился новый оператор

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда понадобился новый оператор, но его нет в синтакс-помощнике, что делать?

18.03.2024    1162    ZhokhovM    2    

4

Когда разработчик платформы не добавил проверку препроцессоров

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Когда разработчик платформы решил пойти на кухню за кофе, а проверку препроцессоров не добавил, и вот тут-то и началось: "Что, опять все сломалось? Ну и кофе же я забыл сделать!".😅

18.03.2024    2692    ZhokhovM    4    

9

Реструктуризация - бесконечная история

Рефакторинг и качество кода Платформа 1С v8.3 Бесплатно (free)

При разработке программ требуемый функционал ставят на первое место, но есть еще и архитектура программы. На горизонте 5-10 лет она становится важнее функционала, который должен работать при масштабировании и росте данных. Реструктуризация 5 терабайтной базы 1С 8.2 в формат 1С 8.3, складывает весь пазл архитектурных просчетов, которые сделали ради функционала. Как это исправить? - для разработки правильной архитектуры, нужно всего лишь сместить фокус с функционала и подумать о «вечном».

29.09.2023    1910    1CUnlimited    15    

22

Чистый код. Мой взгляд на жизнь в макаронных джунглях. Часть 2

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

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

27.09.2023    6970    Lemmonbri    136    

36

Чистый код. Мой взгляд на жизнь в макаронных джунглях. Часть 1

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Россия Бесплатно (free)

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

19.09.2023    4350    Lemmonbri    16    

31

5 подходов при доработке конфигурации 1С, чтобы в будущем не было мучительно больно её обновлять

Архитектура Рефакторинг и качество кода Обновление 1С Платформа 1С v8.3 Бесплатно (free)

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

10.08.2023    9590    0    1c-izhtc    37    

21

Задача на ошибки и неоптимальности при проведении приходной накладной

Рефакторинг и качество кода Платформа 1С v8.3 Конфигурации 1cv8 Бесплатно (free)

Задачу эту дают на собеседованиях, видимо, те франчи, которые не в состоянии оценить человека по резюме и в ходе беседы. По идее задачи, подобные этой, должны давать начинающим студентам. Но дают всем подряд. Итак: мои 5 копеек. Критика приветствуется.

11.07.2023    2214    magic1s    32    

11
Комментарии
В избранное Подписаться на ответы Сортировка: Древо развёрнутое
Свернуть все
1. dandykry 10 30.10.18 13:51 Сейчас в теме
https://refactoring.guru/ru/refactoring/how-to - есть что-то общее с этим ресурсом
Update: заметил, что ресурс указан в публикации
2. brr 182 30.10.18 14:44 Сейчас в теме
Мне кажется есть противоречие между уверждениями:
в одной процедуре лучше избегать смешивания выполнения различных малосвязанных вещей

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


Последнее утверждение вообще крайне спорно, представляю с какими сложностями можно столкнуться тестируя такую функцию.
Риник; Alexjas25; mnemchinov; CSiER; CyberCerber; SlavaKron; +6 Ответить
3. Vladimir Litvinenko 2869 30.10.18 21:33 Сейчас в теме
(2)
Разве то, что функция узкоспециализированная, противоречит тому, что она принимает минимальное количество параметров, необходимых для исполнения, а всё остальное извлекает из доступного ей контекста?

Если существует объект, имеющий состояние, и методы работы с этим объектом, то логично что эти методы должны опираться на контекст - на состояние объекта. Методы, работающие в рамках объекта не должны притворяться максимально независимыми от объекта-владельца. Иначе это "статические" методы и им место за пределами объекта.


Возьмем пример. Можно объявить в модуле объекта обработки или документа функцию и в ней вместо чтения значений реквизитов объекта передавать эти значения как параметры. Может показаться, что это хорошо. Ведь функция становится более универсальной. И даже более тестируемой. Но это не так. Более универсальным методам место в более универсальных модулях - общих модулях или хотя бы модулях менеджеров.


Что касается юнит-тестирования, то тестировать функции, опирающиеся на контекст, следует также, как в большинстве ООП языков. Устанавливаются необходимые свойства этого объекта, в рамках которого работает метод, после чего вызывается метод и результат сравнивается с ожидаемым. Иными словами необходимо временно установить контекст и проверять как метод ведет себя в этих условиях.


Конечно в 1С придерживаться такого подхода сложнее, чем в других языках. У нас ведь всегда есть огромное количество методов глобального контекста. Фактически все методы общих модулей к относятся к нему. Они просто ограничены определенным пространством имен - именем общего модуля. Но при этом остаются по своей сути статическими глобальными методами. И для этих методов контекстом является состояние базы данных или состояние объектов, передаваемых в них как параметры.

Избавиться от большого количество параметров не всегда возможно и по той причине, что эти параметры как правило являются значениями, прочитанными из базы данных. И заставить функцию саму получать эти данные, вместо передачи параметра - значит увеличить нагрузку на СУБД и канал связи между сервером и клиентом.

Тем не менее есть рекомендация и для этого случая - паковать большое количество параметров в Структуру, создавая при этом специальный метод-конструктор для такой структуры, устанавливающий при создании структуры её полям значения по умолчанию: https://its.1c.ru/db/v8std#content:2149184290:hdoc. Это можно рассматривать как параметр this/self в ООП, а метод - как принадлежащий этой структуре данных. С натяжкой конечно. Из за того, что конфигуратор не умеет анализировать какие поля мы создаем в конструкторе, контекстной подсказки мы при этом лишаемся. Но если делать структуры с логичным и минимально необходимым составом полей, то проблем возникать не должно.


P.S.: Вспомнил про контекст. В типовых конфигурациях можно наблюдать как разработчики конфигураций хакают разумные ограничения, заложенные разработчиками платформы. В форме мы не можем объявить метод с директивой &НаКлиентеНаСервере (с контекстом). Так разработчики типовых делают метод &НаКлиентеНаСервереБезКонтекста, куда в качестве параметра передают саму Форму. "Вы нам запретили - а мы вас обхитрим" )) И плодится так процедурный подход даже там, где его можно было бы избежать.
begemot; mivari; SagittariusA; +3 Ответить
4. check2 354 30.10.18 23:20 Сейчас в теме
Следующий пункт – отсутствие комментариев. Лично для меня это один из основных критериев того, что код хороший.

Очень понятная процедура расчёт ебестоимости выпуска РАУЗ в УПП. Там практически нет комментариев, но от их отсутствия она не становится понятнее. Скажем так, критерий отсутствия комментариев условие необходимое для хорошести кода но далеко не достаточное, и оценивать качество кода по отсутствию комментариев в нём я бы не стал.
Риник; +1 Ответить
5. ArchLord42 83 31.10.18 07:10 Сейчас в теме
(4)
Очень понятная процедура расчёт ебестоимости выпуска РАУЗ в УПП. Там практически нет комментариев, но от их отсутствия она не становится понятнее.


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

Смысл весь в том, что в идеале код не должен содержать комментарии, т.е. он должен быть самодокументированным.

Если вы пишите что-то и у вас появляются сомнения, что через пару дней вы и сами не поймете "без бутылки", что этот код делает, а время на рефакторинг нет, то лучшим решением конечно будет написание комментариев, ибо только хороший код (с точки зрения читаемости) без комментариев является хорошим.
6. dm_romanov.idm 31.10.18 08:01 Сейчас в теме
(4)
ИМХО, суть этого пункта в следующем: код должен быть читаем без комментариев.
Если нужны комментарии в коде, значит что-то не то с кодом. Код не достаточно декомпозирован или названия переменных и функций в коде не отражают их назначения.

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

Исключение тут сложные алгоритмы как расчет себестоимости, но их тоже лучше описывать не комментариями в коде, а в отдельных документах с диаграммами.
8. HAMMER_59 244 31.10.18 08:28 Сейчас в теме
(6) По-моему, полный бред, что код должен быть без комментариев.
Конечно, может появиться иллюзия, что код итак отлично читается. Но это пока находишься в нужном контексте, а когда вернешься к коду через полгода, вот тогда и придет понимание, что не так уж все и однозначно.
Merkalov; PSKMOL; SlavaKron; +3 Ответить
9. dm_romanov.idm 31.10.18 08:38 Сейчас в теме
(8)
Не буду спорить. Скажу лишь о двух больших минусах комментариев:
1. Комментарии имеют свойство устаревать, зачастую их не обновляют при изменении кода, в результате комментарий становится бесполезным или даже вредит, направляя мысль разработчика в противоположную сторону.
2. Комментарии не имеют ценности для бизнеса и пользователей, не привносят в создаваемый продукт новой функциональности.

ИМХО поэтому проще и выгоднее писать и обновлять читаемый код, чем писать и обновлять комментарии.
begemot; kuntashov; +2 Ответить
11. kosmo0 107 31.10.18 09:52 Сейчас в теме
(9) Как всегда, слово комментарии разные люди понимают с некоторыми отличиями.
Есть комментарии которые пишутся в стиле "банальные вещи". А есть комментарии которые указывают на некоторые нюансы.

Например в коде прописано какая-то "лишняя" проверка. И при рефакторинге возникнет дикое желание убрать ее. Либо сидеть и лопатить код в целях понимания ради чего эта проверка. А эта проверка срабатывает в одном случае из 1000 и если пропустить этот случай, то потом полбухгалтерии будет искать причину своей проблемы. И для полного счастья будет этот код в общем модуле куда тыкается полконфигурации.

Другой момент. Это когда комментарии касаются предметной области. То есть, если вы полностью понимаете предметную область - это одно, иначе без комментариев потенциально увеличение времени понимания кода.
Риник; +1 Ответить
15. dm_romanov.idm 31.10.18 10:30 Сейчас в теме
(11)
Я против фанатизма и комментарии действительно бывают нужны, когда они помогают разработчикам разобраться в коде, как в случае с "лишней" проверкой.
Но предметную область описывать в комментариях это ИМХО не правильно, лучше описывать в проектных документах, вики и т.п..
33. check2 354 06.11.18 18:15 Сейчас в теме
(6)
Исключение тут сложные алгоритмы как расчет себестоимости, но их тоже лучше описывать не комментариями в коде, а в отдельных документах с диаграммами.

Об этом и речь, что не нужно всё под одну гребёнку.
7. HAMMER_59 244 31.10.18 08:25 Сейчас в теме
Крайне спорное утверждение: "Нужно стремиться к минимизации кода".
Более того при применении декомпозиции, кода становится не меньше, а больше. Другое дело, что в рамках одной процедуры или функции, кода становится действительно меньше, кроме того и переменных становится меньше в рамках функции либо процедуры.

А вот к минимизации стандартов для написания когда, вот к этому точно стремится, т.к. подразумевается что их нужно применять регулярно и держать все это в голове.
31. alexsey777 01.11.18 09:33 Сейчас в теме
(7)Согласен. Постоянно рефакторю свой код. В основном в сторону декомпозиции. Чтобы 1 метод выполнял конкретное действие, которое можно определить из названия метода.
В этом случае когда становится больше, но его гибкость и понятность увеличивается.
10. SagittariusA 31.10.18 09:29 Сейчас в теме
12. AlexGroovy 31.10.18 10:12 Сейчас в теме
Краткий смысл всей статьи -"Harder,better,faster,stronger"
13. MikhailDr 31.10.18 10:15 Сейчас в теме
Я думал комментарий нужен не столько для того, чтобы можно было понять о чем код, сколько для того, чтобы ускорить этот процесс. Т.е. маленький комментарий "Расчет скидки для прайсовой цены" ты прочитаешь гораздо быстрее, чем самый грамотно написанный код расчета этой скидки.
rpgshnik; +1 Ответить
14. spacecraft 31.10.18 10:20 Сейчас в теме
(13)
Т.е. маленький комментарий "Расчет скидки для прайсовой цены" ты прочитаешь гораздо быстрее, чем самый грамотно написанный код расчета этой скидки.

Если в коде необходим такой комментарий, то это первый признак необходимости рефакторинга этого кода: вынос этого участка кода в отдельный метод с соответствующим именем.
kuntashov; +1 Ответить
17. MikhailDr 31.10.18 10:42 Сейчас в теме
(14) Хорошо, неудачный пример. Вот из последнего, у бухгалтерии не выводились в печатной форме авансового отчета должность и подразделение физического лица. Залез в код, на формирование печатной формы работает масса процедур и функций и вот например

// Возвращает таблицу значений содержащую поля ФизическоеЛицо и Сотрудник. Сотрудник отбирается по принципам:
// - Работает на указанный период.
// - Выбирается сотрудник, работающий по основному месту работы, если такового не существует, выбирается
// сотрудник, работающий по совместительству, принятый на наиболее раннюю дату.
//
// Параметры:
// СписокФизическихЛиц - Массив ссылок на элементы справочника ФизическиеЛица или
// - СправочникСсылка.ФизическиеЛица
// - Неопределено - в таблицу войдут "основные" сотрудники всех
// физических лиц когда либо работавших в организации.
// ТолькоРазрешенные - Булево
// Организация - СправочникСсылка.Организации
// Период - Дата
//
//
// Возвращаемое значение:
// ТаблицаЗначений - Таблица значений, содержащая поля Сотрудник и соответствующее сотруднику ФизическоеЛицо.
//
Функция ОсновныеСотрудникиФизическихЛиц(СписокФизическихЛиц, ТолькоРазрешенные, Организация, Период) Экспорт


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

Я конечно соглашусь с тезисом, что если без комментария нельзя понять, что делает функция, то это плохой код, но вот установка, что сам факт наличия комментария говорит о плохом коде меня смущает.
rpgshnik; Vladimir Litvinenko; +2 Ответить
18. spacecraft 31.10.18 10:56 Сейчас в теме
(17) тут нужно разделить понятия: комментирование кода и комментарий метода. Последний нужен. Он нужен в первую очередь, как документация. Он не расписывает сам код.
19. MikhailDr 31.10.18 11:11 Сейчас в теме
(18) Но в статье то все категорично

Следующий пункт – отсутствие комментариев. Лично для меня это один из основных критериев того, что код хороший. А так я с вашим тезисом согласен
20. spacecraft 31.10.18 11:18 Сейчас в теме
(19) далее же описано: "Если код требуется комментировать, это плохой код". В (17) приведен комментарий не кода, а описание интерфейса ( не путать с UI - пользовательский интерфейс).
Возможно в статье это неявно выражено, но понимается это именно так.
21. spacecraft 31.10.18 11:33 Сейчас в теме
(19) да, есть еще направление, которое не приемлет вообще никакого комментария. В том числе и описания методов. Это "экстремальное программирование", основанное на TDD. Но там "комментариями"" служат тесты. К 1С это нормально применить практически невозможно.
В любом случае все сходятся к тому, что внутри метода комментарии излишни.
16. dm_romanov.idm 31.10.18 10:32 Сейчас в теме
(13)
Процедура или функция "РасчетСкидкиДляПрайсовойЦены" читается не хуже.
22. _LkMaksimka_ 1 31.10.18 12:18 Сейчас в теме
Комментарий нужен краткий который позволяет понять, что делает функция(процедура) и что возвращает функция. А комментарии, которые описывают каждую строку функции или процедуры, не нужны.
rpgshnik; +1 Ответить
23. vadim1011985 99 31.10.18 12:40 Сейчас в теме
У всех свое понятия комментария лично я понял это так : не нужно комментировать что делает код построчно например :

Для каждого книга из библиотеки Цикл // перебираем книги в библиотеке 

// переместим все книги из одного помещения в другое 
.....
.....
.....

КонецЦикла 


т.е. код должен быть читаемым без всяких комментариев.

Но комментарии нужны для описания общих действий например

кусочек кода из типовой БП


Процедура СформироватьДвиженияПереоценкаВалютныхОстатков(ТаблицаВалютныхОстатков, ТаблицаРеквизиты, Движения, Отказ) Экспорт
	
	Если Не ЗначениеЗаполнено(ТаблицаРеквизиты)
	 Или Не ЗначениеЗаполнено(ТаблицаВалютныхОстатков) Тогда
		Возврат;
	КонецЕсли;
	
	Параметры = ПодготовитьПараметрыПереоценкаВалютныхОстатков(ТаблицаВалютныхОстатков, ТаблицаРеквизиты);
	Реквизиты = Параметры.Реквизиты[0];
	
	Дата              = Реквизиты.Период;
	Организация       = Реквизиты.Организация;
	
	ТаблицаПереоценка = Параметры.ТаблицаПереоценка;
	Проводки        = Движения.Хозрасчетный;
	
	// С целью оптимизации производительности напрямую (а не через функции с повторно используемыми значениями) кешируем
	// свойства счетов. При заполнении субконто исключаем лишние проверки на значения субконто (наличие субконто на счете
	// и т.п. существующие в алгоритме как предусловия).
	СчетаПереоценкиКеш = Новый Соответствие;
Показать
_LkMaksimka_; +1 Ответить
24. spacecraft 31.10.18 13:03 Сейчас в теме
(23) вот как раз второй кусок кода яркий пример "нехорошего кода".
1. комментарий внутри метода не читаем. Не все его вообще прочитают. При свернутом методе так точно.
2. Метод сложный. В нем наворочено много разнородных действий.
Этот кусок кода явно нуждается в рефакторинге. Несвязанные действия с прямым назначением метода необходимо выделить в отдельные методы.
25. vadim1011985 99 31.10.18 13:22 Сейчас в теме
(24) Я просто показал пример , на счет нечитаемости - по-моему это чисто субъективно , для меня он нормально читаем , если надо разобраться как работает функция вы ее все-же разворачиваете (это про свертываемость) На счет сложности - опять же чисто субъективно , но спорить не буду.
26. spacecraft 31.10.18 13:45 Сейчас в теме
(25)
на счет нечитаемости - по-моему это чисто субъективно , для меня он нормально читаем , если надо разобраться как работает функция вы ее все-же разворачиваете (это про свертываемость)

Смотрим. Функция экспортная, значит это интерфейсная функция. Если по названию и описанию к функции невозможно понять, что она делает и нужно разворачивать функцию и изучать код, значит что-то не то с самой функцией.
Если в интерфейсной функции много действий, которые еще и отдельно комментировать нужно... это вообще атас.
27. vadim1011985 99 31.10.18 14:23 Сейчас в теме
(26) А Вы отладку делаете ? Например идет неправильная переоценка и я хочу найти откуда растут руки, мне надо проверить корректность данных , поэтому я ее разворачиваю и читаю Экспортная функция еще не означает что она интерфейсная Опять же другой пример из типовой . Я специально убрал комментарий указания типа у "ВидСклада" , сейчас не важно по какой причине я открыл данную функцию , вопрос - если бы не было комментария смогли бы вы определить какой тип надо поставлять в данный параметр ? Наверно смогли бы открыв код где заполняются эти параметры и посмотрев , но это убивает время

Функция ПодготовитьПараметрыРасчетТорговойНаценки(ТаблицаРасчетНаценки, ТаблицаРеквизиты)
	
	Параметры = Новый Структура;
	
	// Подготовка таблицы Параметры.ТаблицаПроводокРасчетНаценки
	
	СписокОбязательныхКолонок = ""
	+ "ПродажнаяСтоимостьРеализация,"         // <Число, 15, 2>
	+ "ПродажнаяСтоимостьОстаток,"         // <Число, 15, 2>
	+ "ТорговаяНаценкаОстаток,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокНУ,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокПР,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокВР,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидки,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиНУ,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиПР,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиВР,"  // <Число, 15, 2>
	+ "СуммаНаценки,"         // <Число, 15, 2>
	+ "СуммаНаценкиНУ,"       // <Число, 15, 2>
	+ "СуммаНаценкиПР,"       // <Число, 15, 2>
	+ "СуммаНаценкиВР,"       // <Число, 15, 2>
	+ "СчетДт,"               // <ПланСчетовСсылка.Хозрасчетный>
	+ "СчетКт,"               // <ПланСчетовСсылка.Хозрасчетный>
	+ "ВидСклада,"            // ????????
	+ "ЕстьПартии,"           // <Булево>
	+ "ЕстьСтавкиНДС,"        // <Булево>
	+ "Склады,"               // <СправочникСсылка.Склады>
	+ "Партии,"
	+ "СтавкиНДС,"            // <ПеречислениеСсылка.СтавкиНДС>
	+ "Номенклатура,"         // <СправочникСсылка.Номенклатура>
	+ "НоменклатурныеГруппы," // <СправочникСсылка.НоменклатурныеГруппы>
	+ "Подразделение"         // <Ссылка на справочник подразделений>
	;
	
	Параметры.Вставить("ТаблицаПроводокРасчетНаценки", 
		ОбщегоНазначенияБПВызовСервера.ПолучитьТаблицуПараметровПроведения(ТаблицаРасчетНаценки, СписокОбязательныхКолонок));
		
	СписокОбязательныхКолонок = ""
	+ "ПродажнаяСтоимостьРеализация,"         // <Число, 15, 2>
	+ "ПродажнаяСтоимостьОстаток,"         // <Число, 15, 2>
	+ "ТорговаяНаценкаОстаток,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокНУ,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокПР,"  // <Число, 15, 2>
	+ "ТорговаяНаценкаОстатокВР,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидки,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиНУ,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиПР,"  // <Число, 15, 2>
	+ "ПроцентСкидкиНакидкиВР,"  // <Число, 15, 2>
	+ "СуммаНаценки,"         // <Число, 15, 2>
	+ "СуммаНаценкиНУ,"       // <Число, 15, 2>
	+ "СуммаНаценкиПР,"       // <Число, 15, 2>
	+ "СуммаНаценкиВР,"       // <Число, 15, 2>
	+ "ВидСклада,"            // ????????
	+ "СчетКт,"               // <ПланСчетовСсылка.Хозрасчетный>
	+ "Склады,"               // <СправочникСсылка.Склады>
	+ "Партии,"
	+ "СтавкиНДС,"            // <ПеречислениеСсылка.СтавкиНДС>
	+ "Номенклатура,"         // <СправочникСсылка.Номенклатура>
	+ "Подразделение"         // <Ссылка на справочник подразделений>
	;
	
	Параметры.Вставить("ТаблицаДвиженийРегистраРасчетНаценки", 
		ОбщегоНазначенияБПВызовСервера.ПолучитьТаблицуПараметровПроведения(ТаблицаРасчетНаценки, СписокОбязательныхКолонок));
	
	// Подготовка таблицы Параметры.Реквизиты
	
	СписокОбязательныхКолонок = ""
	+ "Период,"                          // <Дата>
	+ "НачДата,"                         // <Дата>
	+ "КонДата,"                         // <Дата>
	+ "Организация,"                     // <СправочникСсылка.Организации>
	+ "Регистратор,"                     // <ДокументСсылка.*>
	+ "Содержание"                       // <Строка, 150>
	;
	
	Параметры.Вставить("Реквизиты", 
		ОбщегоНазначенияБПВызовСервера.ПолучитьТаблицуПараметровПроведения(ТаблицаРеквизиты, СписокОбязательныхКолонок));
	
	Возврат Параметры;
	
КонецФункции // ПодготовитьПараметрыРасчетТорговойНаценки()
Показать
28. spacecraft 31.10.18 14:48 Сейчас в теме
(27) Если метод помечен как экспортный, то он по определению становится интерфейсным данного модуля. К нему могут обращаться извне.
Что делает конкретный служебный метод, для пользователя интерфейса не важно.
В данном случае, если требуется отладка служебного метода, значит этот код не может быть хороший, если только не сами его пишите.
вопрос - если бы не было комментария смогли бы вы определить какой тип надо поставлять в данный параметр ?

Если необходимо извне узнавать тип передаваемого параметра из комментария внутри служебного метода... это точно нехороший код.

Поймите, нехороший код это не означает нерабочий код, или что он работает медленнее. Это означает, что этот код можно рефакторить.
Vladimir Litvinenko; +1 Ответить
29. dm_romanov.idm 31.10.18 15:08 Сейчас в теме
(27)
Здесь можно было использовать структуру вместо строки и вместо комментария задавать тип значения в коде. Читаемость была бы не хуже, всё равно внутри метода он переводит в структуру.

К сожалению, 1С достаточно бедный язык, там где разработчики указывают тип в комментарии в других языках указывают тип в коде. Что служит и защитой от неверно переданных параметров и помогает автодополнению.
30. Leits 1 01.11.18 09:27 Сейчас в теме
32. rpgshnik 3631 06.11.18 04:58 Сейчас в теме
С комментарием не согласен. Хорошо когда и код легко читаемый и комментарий хороший.

Про параметры тоже не согласен. Бывают случаи когда да необходимо указать с десяток параметров. Частные но необходимые случаи.

В остальном об этом уже и здесь и везде писали не однократно. Вот только красивый код это как искусство, кому-то дано, кому-то нет. Дано увы малому проценту и если из этого процента состоит ваша команда то круто!
Прикрепленные файлы:
34. AlexCherdakov 20 21.11.18 11:09 Сейчас в теме
со всем согласен главное не переусердствовать, например стремление к "минимуму строк кода" без оглядки на его читаемость, полный отказ от комментирования кода и т.п. Короче стремление к "хорошести" кода ради самой "хорошести" это классическая подмена ценностей...
dima_home; +1 Ответить
Оставьте свое сообщение