ISSN 0236-235X (P)
ISSN 2311-2735 (E)

Journal influence

Higher Attestation Commission (VAK) - К1 quartile
Russian Science Citation Index (RSCI)

Bookmark

Next issue

2
Publication date:
16 June 2024

Code refactoring. Basic approaches

The article was published in issue no. № 2, 2013 [ pp. 188-191 ]
Abstract:The paper substantiates the code refactoring application during the iterative software development lifecycle. The code refactoring principles and motives are described to show its advantages including improving code readability and reducing complexity. The most common and important refactoring techniques are used to improve the source code of the software package for mathematical modeling of the forming fibers. The results of the code refactoring are reviewed at the end of the paper.
Аннотация:Обосновывается применение рефакторинга исходного кода между итерациями разработки при использовании в разработке программного продукта итерационной модели жизненного цикла ПО. Рассматриваются принципы и при-чины рефакторинга кода как средства улучшения его читабельности и композиционной стройности структуры про-граммы. На примере программного пакета для математического моделирования процессов формования волокон описываются основные и наиболее необходимые методы рефакторинга, в том числе замена именований функциональных частей программы (классов, их полей и методов), передвижение полей и методов по иерархии классов при использовании наследования, выделение и встраивание классов, выделение методов, комментирование узких мест кода (расчетных алгоритмов специфической предметной области). Как итог рассматриваются результаты проведенного рефакторинга.
Authors: Kalabin, A.L. (alex.ka.86@gmail.com) - Tver State Technical University, Tver , Russia, Ph.D, () - , Russia,
Keywords: code refactoring, software architecture, mathematical and computer modeling
Page views: 12847
Print version
Full issue in PDF (7.68Mb)
Download the cover in PDF (1.35Мб)

Font size:       Font:

Одной из самых популярных моделей жизненного цикла ПО является итерационная модель. Она предполагает разбиение жизненного цикла на последовательность итераций, каждая из которых напоминает мини-проект, включая все процессы разработки в применении к созданию меньших фрагментов функциональности по сравнению с проектом в целом. Цель каждой итерации – получение работающей версии программной системы, включающей функциональность, определенную интегрированным содержанием всех предыдущих и текущей итераций. Результат финальной итерации содержит всю требуемую функциональность продукта. Однако интеграция новых модулей (классов, методов) на каждой итерации разработки не может происходить без модификации старых. При этом сложность интеграции зависит в основном от композиционной стройности программы, полученной на предыдущей итерации разработки. Таким образом, зачастую доработка функционала сопровождается изменением программной архитектуры в той или иной степени. Внесение в исходный код модификаций, которые не влияют ни на функциональность, ни на скорость работы, однако приводят к улучшению структуры и уменьшению связности программных слоев, называется рефакторингом [1].

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

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

При проведении рефакторинга оказывается, что соотношение разных этапов работ изменяется. Проектирование непрерывно осуществляется во время разработки, а не выполняется полностью заранее. При реализации системы становится ясно, как можно улучшить ее структуру. Происходящее взаимодействие приводит к созданию програм- много продукта, качество которого остается высоким по мере продолжения разработки [1–3].

Цель данной статьи – описание основных приемов и методов рефакторинга и иллюстрация его эффективности на примере программного пакета «Конструктор» [4] для моделирования технологических процессов.

Программный пакет «Конструктор» разработан для объединения имеющихся реализаций математических моделей существенно различающихся процессов формования химических волокон в одном программном средстве [5]. Разработанное программное решение должно было применяться в химической промышленности при подборе параметров оборудования, метрологическом контроле объектов технологической схемы, а также при моделировании экспериментов в научных целях. Основными его достоинствами должны были стать использование технологии многопоточности, архитектуры «Документ/Представление» и наглядное отображение результатов расчета в виде настраиваемых графиков.

Важно понимать, что при решении матема- тических моделей различных процессов использованы одни и те же численные методы: интегрирование дифференциальных уравнений методом Рунге–Кутта, интерполяция функции методом конечных разностей и методом сплайна, решение систем уравнений методом прогонки и другие. Однако при разработке «Конструктора» расчетные части практически не модифицировались, так как итогом разработки должно было стать пользовательское, а не исследовательское приложение с реализацией подхода визуального моделирования технологических процессов с использованием парадигмы объектно-ориентированного программирования для отображения, обработки пользовательского ввода и сохранения информации. Решение этих задач привело к появлению дублирующего кода и переносу разнообразия подходов из исходных частных программных реализаций в «Конструктор». В результате код программных модулей получился плохо структурированным и содержал повторяющиеся блоки. Это осложняло дальнейшее развитие программного пакета: реализацию отсутствующих математических моделей (например, реализацию математической модели процесса формования полимерного оптоволокна), доработку пользовательского интерфейса, устранение неточностей в логике. Дальнейшая доработка «Конструктора» выявила необходимость рефакторинга исходного кода программного пакета.

Рассмотрим подробнее применявшиеся приемы рефакторинга, сгруппированные по семантике.

Введение правильного именования

Имена встречаются в программировании повсеместно, их присваивают переменным, функциям, аргументам, классам и пакетам, исходным файлам и каталогам, в которых они хранятся. Основное правило именования – имя класса, метода, поля и прочего должно передавать намерения программиста и отвечать на все главные вопросы: почему он существует, что делает и как используется. Содержательные имена существенно упрощают понимание и модификацию кода. Если имя требует дополнительных комментариев, значит, оно выбрано неправильно и нужно его изменить.

Рассмотрим это простое правило на примере кода программного пакета «Конструктор».

В классе AerodynamicalMoulding (расчет аэродинамического формования) есть поле, хранящее значение реологической силы.

Приведем три варианта именования:

double fr;//реологическая сила

double freo;//реологическая сила

double reologicalForce.

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

В пакете «Конструктор» был выбран второй вариант именования поля (причем без комментария). В ходе рефакторинга использованы приемы «Переименование поля» (Rename field), «Переименование метода» (Rename method) и «Переименование класса» (Rename class). Названия полей, классов и методов были заменены на «говорящие», что значительно улучшило читабельность и понятность кода.

Улучшение структуры проекта и устранение дублирующегося кода

Еще одно простое правило хорошего кода: он не должен повторяться. Это теория, с которой все согласны, однако на практике происходит иначе. Например, в коде «Конструктора» повторяющиеся фрагменты встречались часто, так как в нем объединялись имеющиеся независимые программные реализации. Так, численные методы, необходимые для расчетов, были реализованы во множестве классов, описывающих различные виды формования.

Например, метод

int Sign(double n)

{

      if(n==0)

             return 0;

      if(n==fabs(n))

             return 1;

      else

             return-1;

}

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

В ходе рефакторинга был использован прием «Выделение класса» (Extract class) – создан отдельный статический класс Solver для реализации методов, общих для многих классов формования. Соответственно, туда был перенесен и уже упомянутый способ «Перемещение метода» (Move method). Кроме того, тело метода переписано с использованием тернарного оператора.

int Solver::sign(double number)

{

return number > 0 ? 1 : number < 0 ? -1 : 0;

}

В этот же класс перенесены численные методы решения системы уравнений методом прогонки, интерполяция функции кубическими сплайнами и др. Из классов, реализующих схемы формования, были перенесены не только повторяющиеся методы, но и повторяющиеся фрагменты кода внутри методов. Для этого использовался прием рефакторинга «Извлечение метода» (Extract method).

Объекты технологической схемы представлены в исходном коде иерархией классов. При этом поля и методы в классах-потомках одного уровня зачастую дублировались полностью или частично. В соответствии с принципами рефакторинга полностью дублированные поля и методы были перенесены в суперклассы – приемы «Подъем поля» (Pull up field) и «Подъем метода» (Pull up method). В ситуации, когда методы классов были неодинаковыми, но схожими, в родительском классе создавался абстрактный метод с унифицированной сигнатурой, реализующий их общий функционал. Классы-потомки, в свою очередь, обеспечивали в переопределенном методе специфическое поведение. Этот прием рефакторинга в литературе известен как «Формирование шаблона метода» (Form Template Method).

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

Комментирование кода

Хотя в большинстве случаев правильное именование полей и методов класса делает код читабельным и вполне понятным при беглом просмотре, иногда комментарии могут разъяснить непрозрачные фрагменты кода [3].      Код программного пакета «Конструктор» описывает специфическую предметную область, поэтому с пониманием методов расчета при ознакомлении с кодом неизбежно возникают проблемы. Он отражает технологический процесс, ряд физико-химических явлений и множество вычислительных методов. Естественно, это требует пояснения комментариями, например:

//Расчет движения границы геля

for(int i=0; i

{

...

//Изменяем Slider в зависимости от положения

//слайдера. Перем-я Slider связана с толщиной

//линии объектов CPen

CString sliderPosition = slider.getPosition();

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

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

Литература

1.     Фаулер М. Рефакторинг: улучшение существующего кода; [пер. с англ.]. СПб: Символ-Плюс, 2003.

2.     Макконнелл С. Совершенный код. Мастер-класс; [пер. с англ.]. СПб: Питер, 2005.

3.     Мартин Р. Чистый код: создание, анализ и рефакторинг. Библиотека программиста. СПб: Питер, 2010.

4.     Калабин А.Л., Керницкий А.В., Пакшвер Э.А. Программная система предпроектных исследований технологических процессов формования химических волокон // Програм- мные продукты и системы. 2008. № 1.

5.     Гамаюнов Н.И., Калабин А.Л., Свистунов В.А. Моделирование диффузии в бикомпонентных волокнах типа ядро-оболочка // Теоретические основы химической технологии. 1994. Т. 28. Вып. 3. С. 285–287.

References

1.  Fowler M., Beck K., Brant J., Opdyke W., Roberts D.,  Re-factoring: Improving the Design of Existing Code, Addison-Wesley Professional, 1999, 431 p.

2.  MacConnell S., Code Complete  : A Practical Handbook of Software Construction, Microsoft Press, 2004.

3.  Martin R.,  Clean Code: A Handbook of Agile Software Craftsmanship, Prentice Hall, 1st ed., 2008.

4.  Kalabin A.L., Kernitsky A.V., Pakshver E.A.,  Programm-nye produkty i sistemy [Software and Systems], Tver, 2008, no. 1.

5.  Gamayunov N.I., Kalabin A.L., Svistunov V.A., Teoreticheskie osnovy khim. tekhnologii  [Theoretical Foundations of Chemical Engineering], 1994, Vol. 28, iss. 3, pp. 285 –287.


Permanent link:
http://swsys.ru/index.php?page=article&id=3491&lang=&lang=en&like=1
Print version
Full issue in PDF (7.68Mb)
Download the cover in PDF (1.35Мб)
The article was published in issue no. № 2, 2013 [ pp. 188-191 ]

Perhaps, you might be interested in the following articles of similar topics: