1с рефакторинг что это
Статья входит в цикл «Первые шаги в разработке на 1С». Она продолжает тему, затронутую в предыдущей статье, и описывает новые приёмы работы, которые появились в конфигураторе платформы «1С:Предприятие 8».
Прочитав статью, вы узнаете:
- Что такое контекстная подсказка и как она помогает при написании программного кода?
- Для чего нужны шаблоны текста и как их применять на практике?
- Зачем использовать группировку строк программного кода?
- Как выделение цветом может улучшить удобство работы с редактором кода?
- В чем удобство нового поиска в дереве конфигурации?
- Как быстро отобразить объекты нужной подсистемы?
- Какие инструменты рефакторинга и отказа от модальности существуют и как ими пользоваться?
Применимость
В статье рассматривается возможности конфигуратора на примере платформы «1С:Предприятие» редакций 1C 8.3.5 – 8.3.11, поэтому вся информация актуальна.
Улучшения в конфигураторе платформы «1С:Предприятие 8.3»
При выпуске новой версии платформы «1С:Предприятие 8.3» разработчики добавили в нее несколько интересных и полезных нововведений, чтобы упростить ежедневный труд сотен разработчиков по всей стране.
Контекстная подсказка
Теперь при написании программного кода модуля в редакторе конфигуратора контекстная подсказка отображает не только допустимые в данном контексте имена переменных и процедур, но и параметры редактируемой в данный момент процедуры или функции.
Новая функциональность доступна как для встроенных процедур, так и для собственных процедур разработчика.
Подсказка со списком параметров выглядит следующим образом:
Для увеличения нажмите на изображение.
Параметр процедуры, который следует сейчас ввести, выделяется жирным шрифтом. Ниже под горизонтальной чертой располагается описание текущего параметра. Если он является обязательным, на этом акцентируется внимание при помощи текста в скобках.
При наличии нескольких вариантов синтаксиса встроенной процедуры в заголовке становятся доступны стрелки, предназначенные для переключения между этими вариантами.
Следующей полезной особенностью новой контекстной подсказки является возможность отображать параметры пользовательских процедур и функций.
Для увеличения нажмите на изображение.
Напомним, что существует документ “Система стандартов и методик разработки конфигураций для платформы 1С:Предприятие 8”, в котором описаны рекомендации фирмы “1С” к разрабатываемому программному коду.
В частности, есть рекомендации по оформлению комментария к заголовку процедуры.
И конфигуратор анализирует комментарии, написанные по таким правилам, и использует их для отображения контекстной подсказки!
Для увеличения нажмите на изображение.
Чтобы избежать ручного написания комментария по приведенному формату, в платформе предусмотрены шаблоны текста, ознакомиться с которыми можно, нажав сочетание клавиш Ctrl + Shift + T.
Шаблон с наименованием “Процедура (с заголовком)” как раз и формирует правильный комментарий.
Чтобы этот шаблон сработал, достаточно набрать в редакторе символы “Проц”, нажать Ctrl+Q и выбрать нужный шаблон из предлагаемого системой списка.
Группировка строк программного кода
Модули типовых решений на платформе “1С:Предприятие 8” достаточно объемные, содержат достаточно большое количество строк кода.
Для повышения удобства чтения и анализа программного кода были реализованы функции группировки условных и циклических операторов, а также процедур.
Во время исполнения программного кода данные инструкции игнорируются. Они нужны только для обозначения сворачиваемых строк кода.
Для увеличения нажмите на изображение.
Нужно следить, чтобы группируемые области не пересекались между собой, потому что в таком случае они не будут сворачиваться на экране.
Выделение цветом конструкций
Теперь в редакторе текста на встроенном языке подсвечиваются цветом синтаксические конструкции, на которых в данный момент установлен курсор. Например, начало и конец процедуры (функции), условного оператора и оператора цикла:
Для увеличения нажмите на изображение.
Еще одним новшеством платформы является выделение цветом открывающихся и закрывающихся скобок. Это очень полезно при написании длинных выражений, когда синтаксический контроль сообщает об ошибке, и разработчику необходимо найти лишнюю или недостающую скобку.
Для увеличения нажмите на изображение.
Для увеличения нажмите на изображение.
Также интерес представляет параметр “Выбранный идентификатор”. Если для него установлен цвет, не совпадающий с цветом фона редактирования, то при двойном щелчке мышью по идентификатору будет подсвечен и он, и все совпадающие идентификаторы в тексте модуля.
Для увеличения нажмите на изображение.
При выполнении поиска в тексте модуля при помощи строки поиска или после нажатия сочетания клавиш Ctrl + F найденное слово выделяется, а все такие же найденные слова подсвечиваются.
Для увеличения нажмите на изображение.
Объединение ячеек табличного документа
Ранее ячейки табличного документа можно было объединить только с помощью пункта меню или соответствующей кнопки командной панели.
Теперь появилось сочетание клавиш Ctrl + M, при нажатии которого и происходит объединение ячеек табличного документа. Также операция “Объединить” доступна в контекстном меню табличного документа.
Надеемся, что и в следующих релизах платформы «1С:Предприятие 8» разработчики будут уделять внимание повышению удобства работы с конфигуратором.
Новые возможности для разработчика в «1С:Предприятие 8.3.5»
Поиск в конфигураторе
Пользоваться поиском при конфигурировании приходится постоянно. Пока конфигурация содержит относительно небольшое количество объектов метаданных, можно осуществлять поиск визуально – глазами, прокручивая дерево конфигурации.
Однако типовые конфигурации достаточно объемны, и при таком подходе поиск будет занимать длительное время.
До выхода платформы 8.3.5 поиск по дереву метаданных можно было осуществить следующим образом:
- набирать с клавиатуры название объекта, при этом система будет искать по совпадению наименования с первой буквы названия, но только в развернутых строках дерева конфигурации;
- при помощи сочетания клавиш Ctrl+F открыть окно поиска:
Найденные объекты будут выведены в окно Результаты поиска, из которого по двойному щелчку мышью можно перейти к нужному объекту метаданных в дереве конфигурации.
В платформе 8.3.5 появилось новое поле поиска, расположенное над деревом конфигурации:
Поиск выполняется по вхождению строки, анализируются свойствам объектов конфигурации Имя, Синоним и Комментарий.
Причем дерево конфигурации фильтруется “на лету”: в нем остаются только объекты, удовлетворяющие введенному фильтру.
Рассмотрим, что обозначают цвета, которыми раскрашены объекты, оставшиеся в дереве после применения фильтра.
Если строка поиска была найдена, то имя такого объекта выделяется в дереве конфигурации черным цветом.
Если кроме того искомая строка присутствует в имени объекта (не в синониме, не в комментарии), то такие вхождения выделяются красным цветом.
Серым цветом выделяются объекты, сами не подходящие под введенный фильтр, но имеющие в своем составе подчиненные (дочерние) объекты, удовлетворяющие заданному фильтру.
На приведенном выше рисунке реквизит ИдентификаторПользователяИБ справочника Пользователи отображается в дереве, т.к. его синоним содержит подстроку “пост”:
Допустимо вводить для поиска несколько подстрок, разделенных пробелами:
Аналогичная строка поиска появилось и у окна, содержащего набор свойств выделенного объекта (палитра свойств):
Найденные свойства будут выведены общим списком, без разбивки по категориям.
Поиск будет осуществляться либо по именам свойств, либо по представлениям свойств (разница приведена на двух скриншотах выше).
Переключиться между режимами имя/представление можно с помощью команды “Отображать имена свойств” контекстного меню:
Такая же строка поиска была добавлена в окне выбора типа данных:
И в окно выбора объекта метаданных (например, выбора регистра сведений, который будет использоваться в качестве графика для регистра расчета):
Быстрое отображение объектов подсистемы
Для быстрого отображения объектов, входящих в одну конкретную подсистему, в контекстном меню появился новый пункт “Объекты подсистемы”:
Напомним, как такого можно было добиться в предыдущих версиях платформы.
Нужно было открыть окно отбора по подсистемам, установить в нем галочку на требуемую подсистему, со всех остальных подсистем галочки снять:
Теперь получить тот же самый результат можно быстрее. Кроме того, чаще всего используется и наиболее востребован отбор именно по одной подсистеме.
А, следовательно, это маленькое удобное новшество сэкономит время разработчика.
Быстрое отображение объектов, захваченных в хранилище
Если конфигурация подключена к хранилищу, то в командной панели над самим деревом конфигурации доступна кнопка “Захваченные объекты”:
Теперь фильтрация выполняется непосредственно в дереве конфигурации, не нужно открывать отдельное окно для работы с хранилищем, в нем устанавливать отборы на захваченные объекты.
Инструменты рефакторинга
Когда над конфигурацией работает группа из нескольких разработчиков, необходимо следить за понятностью кода, следованием общим стандартам.
Контролировать это постоянно не всегда возможно, поэтому периодически проводятся работы по улучшению читаемости кода, пересмотру уже реализованных фрагментов.
Такие действия именуются рефакторингом кода. Это процесс изменения внутренней структуры программы, не затрагивающий её внешнего поведения и имеющий целью облегчить понимание её работы.
Поэтому в конфигураторе платформы 8.3.5 появились механизмы рефакторинга кода и инструменты работы с модальными вызовами.
Они доступны в контекстном меню текстового редактора конфигуратора в отдельном меню Рефакторинг.
Для увеличения нажмите на изображение.
Рассмотрим подробнее реализованные инструменты рефакторинга.
1. Выделить фрагмент
Эта команда преобразует выделенный участок кода в отдельную процедуру или функцию.
Если выделенный участок кода может быть расположен в правой части оператора присваивания, то будет создаваться функция. Рассмотрим пример. Пусть есть фрагмент кода:
Рефакторинг — это процесс изменения кода на встроенном языке с целью сделать код чище, повысить читаемость и улучшить структуру кода не изменяя при этом изначального смысла и внешнего поведения этого кода. Конфигуратор предоставляет несколько инструментов, которые могут помочь при проведении рефакторинга кода в прикладном решении.
Подробнее о каждом из этих инструментов и будет рассказано ниже.
Общие средства рефакторинга
Начнем с общих средств рефакторинга кода, а перед этим напомню, что подробнее о синхронных и асинхронных вызовах можно прочитать в этой статье, а о модальности и блокирующих окнах в этой.
Выделить фрагмент
Эта команда преобразует выделенный фрагмент кода в процедуру или функцию. Фрагмент должен быть синтаксически целостным. Код нового метода располагается сразу после родительского метода.
Если переменные из выделяемого фрагмента используются в оставшейся части родительского метода, то эти переменные передаются новому методу в виде параметров.
Если родительский фрагмент имеет какую-либо директиву компиляции, то новый метод будет иметь точно такую же директиву.
Переименовать
Эта команда предназначена для изменения имен переменных и методов. При переименовании методов-обработчиков в модуле формы выполняется автоматическая замена соответствующих значений свойств элементов формы и команд на правильные.
Для экспортных переменных и модулей выполняется проверка уникальности в рамках конфигурации и отсутствия синонимов среди методов и свойств объектов платформы. Если условие соблюдено, пользователю предлагается глобальная замена идентификатора.
Создать описание метода
Простая команда, которая создает заготовку описания метода. Это описание будет использоваться для контекстной подсказки при использование метода в тексте модулей.
Создать обработку оповещения
Эта команда облегчает применение асинхронных методов. Для того, чтобы команда стала доступна нужно ввести имя метода и открывающую скобку, курсор нужно расположить на имени метода.
Рефакторинг синхронных вызовов
Теперь рассмотрим команды, которые помогают при переходе на асинхронные вызовы
Преобразовать вызов
Эта команда заменяет простые случаи использования синхронных методов на их асинхронные аналоги. Случай не считается простым если, например, использован внутри цикла, внутри перехвата исключения, внутри процедуры, вызываемой из другой процедуры и тд. Для подобных случаев пользователю предлагается выполнить частичное преобразование.
Преобразовать в асинхронную процедуру
Команда преобразует метод к виду, подходящему для использования в асинхронных вызовах. Эту команду следует использовать в тех случаях, когда необходимо преобразовать модальные вызовы внутри процедуры/функции, которая вызывается из других процедур/функций. После использования этой команды нужно превратить модальные вызовы в асинхронные аналоги при помощи команды преобразования модального вызова.
Выделить в асинхронную процедуру
Эта команда превращает выделенный фрагмент кода в отдельную процедуру или функцию, при этом выделенный метод преобразуется к асинхронному виду.
Найти вызовы модуля
Выводит список используемых синхронных методов в текущем модуле.
Преобразовать вызовы модуля
Команда преобразует все простые случаи использования синхронных вызовов в текущем модуле на их асинхронные аналоги.
На этом все, надеюсь, что эта статья была Вам полезна.
Если Вы нашли ошибку или неточность, пожалуйста, выделите фрагмент текста и нажмите Ctrl+Enter.
(оценок: 7, средняя оценка: 5,00 из 5)Пользуйтесь Ctrl+Alt+R в редакторе модулей.
Мотив
Неожиданно выяснилось, что многие знакомые программисты не пользуются подменю Рефакторинг в редакторе модулей конфигуратора. Как ни странно,
- Описания подменю Рефакторинг нет в справке конфигуратора (платформа 8.3.16.1224);
- Описания подменю Рефакторинг нет на Инфостарте;
- В справке конфигуратора сочетание клавиш Ctrl+Alt+R не упоминается.
В результате решил написать об этом статью.
Подменю Рефакторинг
Подменю Рефакторинг доступна в редакторе текста встроенного языка в контекстном меню и в меню Текст.
Подменю Рефакторинг появилось в платформе 8.3.5, которая вышла в августе 2014 года.
Чем же команды подменю Рефакторинг отличаются от других команд меню Текст?
Главное особенность - учет семантики встроенного языка.
Команда Переименовать
Рис 1. Команда Переименовать
Команда Переименовать (Ctrl+Alt+R) - вторая в подменю Рефакторинг. Но (с моей точки зрения) является основной и самой мощной. Давно пользуюсь и до сих пор восхищаюсь простотой и мощью. Особенно Команда Переименовать понравится прокрастинирующим перфекционистам. Теперь можно бесконечно переименовывать переменные, процедуры и функции, не боясь испортить программу.
Команда предназначена для переименования имен переменных и функций.
В отличие от олдскульной Ctrl+H, команда Переименовать понимает, что именно она переименовывает.
Действие команды зависит от текущего положения курсора в тексте модуля.
Рассмотрим варианты:
- Локальная переменная
- Команда изменяет имя локальной переменной в пределах процедуры или функции.
- Команда изменяет имя процедуры или функцию в пределах модуля
- Команда изменяет имя метода-обработчика в модуле и соответствующую ссылку в палитре свойств.
- Команда изменяет имя метода и соответствующий конструктор ОписаниеОповещения.
- Команда изменяет имя глобальной переменной во всех модулях.
- Команда изменяет имя экспортной процедуры или функции во всех модулях. Действует только в модуле, в котором процедура описана.
- Команда недоступна
Команда Выделить фрагмент
Из выделенного фрагмента кода создается новая процедура или функция с постфиксом Фрагмент. А вместо выделенного фрагмента вставляется вызов новой процедуры или функции.
Удобно использовать, когда надо разбить слишком длинную процедуру на несколько частей. Команда все сделает аккуратно, передаст параметры, локальные переменные будут описаны в перечислены в операторе Перем.Команда Создать описание метода
Создает комментарии перед описанием процедуры или функции. Комментарии создаются в стандартном формате, который используется для формирования контекстной подсказки.
Команда Создать обработку оповещения
Помогает создавать обработки оповещения для асинхронных методов типа ПоказатьВопрос().
Пример:Подменю нерекомендуемые синхронные вызовы
Начиная с платформы 8.3.3 фирма 1С придерживается политики отказа от модальных вызовов. Команды подменю предназначена для перехода на асинхронные вызовы.
Функция, используемая для примера, решает задачу разбиения периода времени, заданного начальной и конечной датой, на отрезки, принадлежащие различным месяцам. Пусть в исходном варианте вид функции будет таким -ВАРИАНТ0:
Здесь можно сделать следующее
Можно не выполнять присваивания "Дата1 = ДатаС". Вместо этого достаточно использовать сам параметр «ДатаС» как переменную, а чтобы после выполнения функции его значение не оказалось «испорченным», перед ним в заголовке функции нужно использовать лексему «Знач». Это означает, что параметр передается не «по ссылке», когда используется ранее выделенная переменной память, а «по значению», когда создается новый экземпляр переменной.
Можно сэкономить на придумывании осмысленного названия переменной, предназначенной для вычисляемого значения функции. Если результат функции строится в ходе ее выполнения и должен быть как-то заранее назван, лучше не выдумывать нового термина, так как у функции уже есть имя, а назвать результат выполнения функции в процессе его вычисления просто «Результат» или «Ответ».
Последовательность операторов «Дата3 = Дата2 - 1;Если Дата3 > ДатаПо Тогда Дата3 = ДатаПо КонецЕсли» это всего лишь присвоение значения переменной «Дата3» с учетом ограничения ее значения сверху значением переменной «ДатаПо». Эта задача проще и нагляднее решается с помощью функции «Мин». То есть, если результат выражения должен учесть ограничения на результат сверху или снизу, следует использовать функцию минимум или максимум, которые читаются легче и пишутся короче, чем условный оператор «если» или условный оператор с вопросом.
Конструктор структуры позволяет сразу проинициализировать ее элементы, поэтому вставку элементов можно сократить. Для создания структуры и инициализации ее полей можно пользоваться соответствующей формой конструктора, куда сразу передать имена полей через запятую и значения полей. Так создаются структуры периодов, добавляемых в массив.
Можно не создавать переменную для ссылки на создаваемую структуру. Так как она будет использована лишь однажды – в следующей строке программы. Вместо этого результат можно сразу записать на место его использования. Тогда не нужно будет «вымучивать» названия лишних переменных. Исключением являются случаи, когда промежуточный результат требует пояснения или контроля в процессе отладки. В нашем случае строка и без этого легко читается: в массив-результат добавляется новая структура из полей «НачалоПериода», «КонецПериода», имеющих соответствующие значения.
В результате функция оказывается приведенной к виду ВАРИАНТ1:
Анализируя эту запись, можно придти к выводу, что переменные «ДатаС», «Дата2» и «Дата3» связаны простой зависимостью. "ДатаС" – это начало периода или начало текущего месяца, "Дата2" – это начало следующего, а "Дата3" – конец текущего месяца. Выполним подстановку и
Избавимся от лишних, то есть связанных простой зависимостью, переменных.
В результате этого получаем ВАРИАНТ2:
Внимание: Из-за того, что знак "меньше или равно" в тексте функции неправильно отрабатывается при редактировании статьи на этом сайте, в него добавлен пробел!
Похожий вариант уже публиковался на Инфостарте [?], вот он - ВАРИАНТ3:
Здесь само собой напрашивается применение приемов 3, 4 и 5, в результате чего получается более красивый и компактный ВАРИАНТ4
В общем, результат в варианте 2 уже можно было бы принять, однако функция «Мин» смотрится инородно. Возможно, это от того, что она срабатывает лишь однажды – на самом последнем периоде. И если периодов много – эти сравнения оказываются лишними. Также, кажется, что можно избавиться от переменной «ДатаС», которая всегда на единицу больше конца периода, только что записанного в массив. А если попробовать сначала записать в массив исходный интервал, а затем при необходимости делить его на две записи, выделяя последний месяц в следующую запись? Алгоритм уместился в одном предложении. Возможно, и его запись окажется понятнее и проще?
Чтобы при этом не приходилось затем удалять записи, если интервал «отрицательный», выполним в этом случае обмен «ДатаС» и «ДатаПо». Здесь повторим прием 3 и обойдемся без условных операторов: началом периода будем считать минимум, а концом – максимум значений этих переменных. С точки зрения пользователя функции, это будет удобнее: программисту при записи вызова функции не нужно будет помнить, какую дату записывать первой – меньшую или большую, период можно будет задать и так и так. Функция станет более «робастной», то есть станет лучше защищена от ошибок в исходных данных. Конечно, это будет иметь свою цену - так отсекается возможность использования функции для контроля, что «ДатаС» меньше «ДатаПо». В результате получаем следующий ВАРИАНТ5:
Рассматривая этот результат, можно заметить, что текст «НачалоПериода», «КонецПериода», "Ответ[0]" часто повторяется. Поэтому,
Если запомнить повторяющиеся константы и сложные ссылки в переменных с короткими названиями, длину кода можно сократить.
При этом некоторые переменные, обозначающие в данной функции константы, лучше вообще сделать параметрами функции и проинициализировать в описании параметров. В данном случае это касается названия полей структуры. Кроме сокращения записи, это придает функции дополнительную гибкость, расширяя варианты ее использования.
Прием 8 заслуживает демонстрации еще одним примером. Вот функция для получения количества элементов массива, равных образцу, с использованием приема 8.
Если массив «Слова» хранит слова программного кода некоторой функции, то выражение
рассчитает показатель цикломатической сложности функции.
Возвращаясь к исходной функции, применение приемов 7 и 8 дает следующий результат - ВАРИАНТ6:
Рассматривая текущий вариант функции, можно заметить повтор в четырех местах названия функции «НачалоМесяца». Если это название разделить на два слова и сделать второе из них параметром функции, то она станет более универсальной, сможет выполнять разбивку на «Минуты», «Часа», «Дни», «Недели», «Месяца», «Квартала», «Года» (по понятным причинам придется смириться с некоторым диссонансом в произношении названий периодов). Для этого нам понадобится функция «Выполнить», которая воспринимает код как строку и выполняет его. В исходном коде название функции заменяется на «_», то есть «впишите что хотите», а перед выполнением туда вписывается нужный интервал заменой подстроки. В данном случае применяется наиболее спорный, ухудшающий понимание программы, прием
Универсализации кода с использованием оператора «Выполнить». Этот прием следует применять с осторожностью.
Получаем следующий ВАРИАНТ7:
Переменная «Ответ» заменена однобуквенной переменной «М» для сокращения длины строковой константы, содержащей шаблонизированный код.
Оглядев результат, видим, что в последнем варианте совершенно потеряна простота и понятность кода, которая ранее оправдывала менее компактную запись функции в варианте 5. Поэтому вернемся к варианту 2 и применим к нему приемы 7, 8 и 9. Здесь мы используем прием
Сохранение промежуточных вариантов улучшения кода и возврат к ним из тупиковых ветвей процесса рефакторинга.
В итоге получили следующую универсальную функцию, решающую поставленную задачу (знак "_" заменен словом "Край", что обеспечивает читабельность функции внутри строки ), ВАРИАНТ8:
Можно предложить еще дальше и переписать функцию на английский. Получим последний, десятый ВАРИАНТ9
В прилагаемой к статье обработке приведены все вышеописанные функции с возможностью их тестирования.
Нужно сказать, что улучшение кода – процесс, результат которого не всегда можно оценить однозначно. Объективная составляющая оценок представлена метриками кода. Значения метрик компактности и цикломатической сложности [Анализ цикломатической сложности кода] для всех промежуточных вариантов рассматриваемой функции приведены в таблице.
Номер варианта Число строк Число знаков Цикломатическая сложность Произвольный период 0 21 494 4 Нет 1 14 348 3 Нет 2 8 255 2 Нет 3 12 385 4 Нет 4 9 279 2 Нет 5 9 469 2 Нет 6 10 399 2 Нет 7 9 407 1 Да 8 5 263 1 Да 9 5 242 1 Yes! Субъективная составляющая оценок отражает простоту и понятность кода. Применяя все перечисленные приемы исключительно в погоне за компактностью, можно пропустить момент утраты понятности кода, то есть важно вовремя затормозить. Но когда? Наверное, каждый должен решать сам. В конце концов, кто-то считает, что «тормоза придумали трусы», а кто-то: «тише едешь – дальше будешь».
Читайте также: