Рефакторинг. Зачем? - [2]
Какие можно привести примеры:
— практически все называют переменные цикла буквами i, j, k, для циклов первой, второй и третьей вложенности соответственно;
— какие–то временные, короткоживущие переменные часто снабжают префиксом «temp» или «tmp», например, tempFileName для файла, который вскоре удалится;
— логические переменные становятся куда нагляднее с префиксами типа is, has, can, например, isButtonVisible, canAddPoint, hasPoint;
— в случае коптрования данных из одной переменной в другую, лучше использовать префиксы source и dest, а не суффиксы 1 и 2, «copy(array1, array2)» выглядит менее понятно, чем «copy(sourceArray, destArray)».
Примеры можно приводить бесконечно, понимание таких вещей обычно приходит с опытом. Важно то, что если у функции или переменной есть какая–то особенность, которую можно подчеркнуть слегка поменяв название — почему не сделать это. Когда читаешь код — важна каждая мелочь. Это как в детективе — любой штрих может привести к разгадке. Только в отличии от преступников, программисты обычно делают что–то полезное или на худой конец безвредное, и большое количество деталей тут только в плюс.
Преобразование одной большой функции в две маленькие
Сейчас мы добрались до куда более сложной и куда менее однозначной темы. Дело в том, что человеческое восприятие так устроено, что анализировать сразу большой объём информации ему крайне сложно. Именно по этому, книги принято разбивать на главы, а сами главы на абзацы.
В программировании всё обстоит немного иначе и это может быть причиной путаницы. Тут текст разбит на функции (процедуры, методы, классы, сейчас это не так важно), а основное назначение функций — это возможность их повторного использования. То есть по сути, с их помощью суммарный объём кода уменьшается, они позволяют избежать многократного повторения одних и тех же фрагментов кода и тому подобное.
Использование функций как инструмента для улучшения читабельности кода, на мой взгляд, сильно недооценёно. Как показывает практика, небольшое усложнение кода ухудшает его восприятие значительно.
>type
>TRect = record
>Left: Integer;
>Right: Integer;
>Top: Integer;
>Bottom: Integer;
>end;
>function RectsLength(Rects: array of TRect): Integer;
>var
>I: Integer;
>Width, Height: Integer;
>begin
>Result:= 0;
>for I:= 0 to Length(Rects) — 1 do
>begin
> Width:= Rects[I].Right — Rects[I].Left;
>Height:= Rects[I].Bottom — Rects[I].Top;
> Result:= Result + 2 * Width + 2 * Height;
>end;
>end;
Выше приведён простой пример, который рассчитывает сумму периметров прямоугольников в массиве. Пока он не выглядит сильно сложным, но, предположим, что задача немного изменилась и нам сказали не учитывать прямоугольники площадью меньше некоего числа MinLength.
>function RectsLength(Rects: array of TRect; MinLength: Integer): Integer;
>var
>I: Integer;
>Width, Height, Len: Integer;
>begin
>Result:= 0;
>for I:= 0 to Length(Rects) — 1 do
>begin
> Width:= Rects[I].Right — Rects[I].Left;
>Height:= Rects[I].Bottom — Rects[I].Top;
>Len:= 2 * Width + 2 * Height;
>if Len >= MinLength then
> Result:= Result + Len;
>end;
>end;
Не скажу, что намного сложнее, но взгляд спотыкается. А если бы мы сразу выделили функцию RectLenght, считающую площадь отдельного прямоугольника вышло бы несколько проще:
>function RectLength(Rect: TRect): Integer;
>var
>Width, Height: Integer;
>begin
> Width:= Rect. Right — Rect. Left;
>Height:= Rect. Bottom — Rect. Top;
>Result:= 2 * Width + 2 * Height;
>end;
>function RectsLength(Rects: array of TRect; MinLength: Integer): Integer;
>var
>I: Integer;
>Len: Integer;
>begin
>Result:= 0;
>for I:= 0 to Length(Rects) — 1 do
>begin
>Len:= RectLength(Rects[I]);
>if Len >= MinLength then
>Result:= Result + Len;
>end;
>end;
И пусть вас не смущает, что в сумме кода стало немного больше. Мне ещё ни разу не приходилось жалеть о такого рода рефакторинге. То есть были, конечно, случаи, когда он был не оправдан и только путал… У каждого бывали ошибки. Но никогда проблемы не были связаны с увеличением суммарного объема кода. Иногда, даже если вы смогли разделить функцию на две функции того же размера (суммарное увеличение кода в два раза), но, при этом хорошо разделили их логически — это бывает оправдано.
Я не хочу сказать, что разбить большую функцию на две или несколько маленьких можно и нужно всегда. Принять решение об этом — задача, в ряде случаев, очень сложная. Поэтому, я хотел бы посвятить следующую главу признакам необъодимости такого рефакторинга.
Признаки необходимости выделения функции
Как я уже написал выше — тема довольно сложная и неоднозначная. Подобных признаков может быть сколько угодно, у каждого они свои, но какие–то общие рекомендации на основании своего опыта я постараюсь дать.
1. Размер функции. Первое, что должно насторожить — это слишком большой размер функции. Проще всего измерять их в экранах. Экран в данном случае — это количество кода, которое вы можете увидеть без использования прокрутки. Лучше всего читаются функции, влезающие на экран полностью.
И это не связано с «лишней работой» в виде листания текста. Дело в том, что даже в художественной литературе, для полного понимания, приходится возвращаться к началу абзаца. Что уж говорить о коде, который, зачастую, куда менее линеен.

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

Несколько слов об особенностях JavaScript, другими словами - что я знал об этом языке до начала его изучения. Первое и главное: JS код легко интегрируется в HTML разметку и является де факто стандартом для интернет браузеров. Из этого следует, что если вы совершенно не знаете HTML - JS, вероятнее всего, будет для вас бесполезна. В данном опусе я постараюсь разжевать всё максимально детально, но надо иметь в виду, что HTML и JS идут бок о бок, дополняя, а не заменяя друг друга. Для тех, кто сталкивался раньше с Delphi программированием или чем-то подобным можно, в первом приближении, привести такую аналогию: HTML - это форма, а JS - сам код программы.Другая важная особенность языка - высокая интерактивность.

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

Java Enterprise Edition (Java EE) остается одной из ведущих технологий и платформ на основе Java. Данная книга представляет собой логичное пошаговое руководство, в котором подробно описаны многие спецификации и эталонные реализации Java EE 7. Работа с ними продемонстрирована на практических примерах. В этом фундаментальном издании также используется новейшая версия инструмента GlassFish, предназначенного для развертывания и администрирования примеров кода. Книга написана ведущим специалистом по обработке запросов на спецификацию Java EE, членом наблюдательного совета организации Java Community Process (JCP)

Что такое ГЕЙМДИЗАЙН? Это не код, графика или звук. Это не создание персонажей или раскрашивание игрового поля. Геймдизайн – это симулятор мечты, набор правил, благодаря которым игра оживает. Как создать игру, которую полюбят, от которой не смогут оторваться? Знаменитый геймдизайнер Тайнан Сильвестр на примере кейсов из самых популярных игр рассказывает как объединить эмоции и впечатления, игровую механику и мотивацию игроков. Познакомитесь с принципами дизайна, которыми пользуются ведущие студии мира! Создайте игровую механику, вызывающую эмоции и обеспечивающую разнообразие.

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

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

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

Python - объектно-ориентированный язык сверхвысокого уровня. Python, в отличии от Java, не требует исключительно объектной ориентированности, но классы в Python так просто изучить и так удобно использовать, что даже новые и неискушенные пользователи быстро переходят на ОО-подход.