Файл: Руководство по стилю программирования и конструированию по.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 864
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
ГЛАВА 24 Рефакторинг
569
вержен ошибкам. Большинство людей естественным образом стараются избегать таких проблемных фрагментов кода,
однако вы добьетесь большего успеха, если будете рассмат- ривать их как мишени рефакторинга (Jones, 2000).
Выполняйте рефакторинг сложных модулей Другим подходом к рефакторингу является концентрация на моду- лях, имеющих максимальные оценки сложности (см. подраздел «Как измерить слож- ность» раздела 19.6). Одно классическое исследование показало, что использова- ние этой методики при сопровождении программ приводило к существенному повышению их качества (Henry and Kafura, 1984).
При сопровождении программы улучшайте фрагменты, к которым при-
касаетесь Код, который никогда не изменяется, не требует рефакторинга. Но если вы все же изменяете фрагмент кода, убедитесь, что вы оставляете его в луч- шем состоянии, чем обнаружили.
Определите интерфейс между аккуратным и безобразным кодом и пере-
местите безобразный код на другую сторону этого интерфейса «Реаль- ность» часто оказывается грязнее, чем нам хотелось бы. Эта грязь может быть обусловлена сложными бизнес-правилами, интерфейсами с оборудованием, про- граммными интерфейсами и т. д. При работе со старыми системами часто при- ходится иметь дело с плохим кодом, который тем не менее должен постоянно оставаться работоспособным.
Эффективной стратегией омоложения внедренных старых систем является опре- деление фрагментов, относящихся к грязному реальному миру, фрагментов, фор- мирующих идеализированный новый мир, и фрагментов, определяющих интер- фейс между двумя мирами (рис. 24-2).
Рис. 24-2. Ваш код не обязан быть грязным только потому, что таков реальный
мир. Рассматривайте систему как комбинацию идеального кода, грязного кода
и интерфейса между идеальным и грязным кодом
Перекрестная ссылка О коде,
подверженном ошибкам, см.
подраздел «Какие классы со- держат наибольшее число оши- бок?» раздела 22.4.
570
ЧАСТЬ V Усовершенствование кода
Работая с системой, вы можете постепенно перемещать грязный код через «интер- фейс между двумя мирами» в более организованный идеальный мир. Если вы толь- ко начинаете работать с унаследованной системой, она может почти полностью относиться к грязному миру. Одна эффективная политика подразумевает, что каж- дый раз, когда вы прикасаетесь к какому-то фрагменту грязного кода, вы должны привести его в соответствие с текущими стандартами кодирования, присвоить пе- ременным ясные имена и т. д. — иначе говоря, переместить его в идеальный мир.
Со временем это может обеспечить быстрое улучшение базы кода (рис. 24-3).
Рис. 24-3. Одной из стратегий улучшения готовой системы является постепенный
рефакторинг плохого унаследованного кода — перемещение его на другую сторону
«интерфейса между двумя мирами»
Контрольный список: безопасный рефакторинг
Является ли каждое изменение частью систематичной стратегии изменений?
Сохранили ли вы первоначальный код перед началом рефакторинга?
Стараетесь ли вы ограничить объем каждого вида рефакторинга?
Выполняете ли вы отдельные виды рефакторинга по одному за раз?
Составили ли вы список действий, которые собираетесь предпринять во время рефакторинга?
Ведете ли вы список видов рефакторинга, которые следовало бы выпол- нить позднее?
Выполняете ли вы регрессивное тестирование после каждого вида рефак- торинга?
Выполняете ли вы обзор сложных изменений и изменений, влияющих на критически важный код?
Рассматриваете ли вы рискованность отдельных видов рефакторинга и адап- тируете ли вы свой подход соответствующим образом?
Убеждаетесь ли вы, что изменения улучшают внутреннее качество программы,
а не ухудшают его?
Не рассматриваете ли вы рефакторинг как оправдание написания плохого кода или как способ избежать переписывания плохого кода?
http://cc2e.com/2457
ГЛАВА 24 Рефакторинг
571
Дополнительные ресурсы
Процесс рефакторинга имеет много общего с процессом устранения дефектов (см. раздел 23.3). Факторы риска, свя- занные с рефакторингом, похожи на факторы риска, каса- ющиеся оптимизации кода. Об управлении факторами риска при оптимизации кода см. раздел 25.6.
Fowler, Martin.
Refactoring: Improving the Design of Existing Code. Reading, MA: Add- ison Wesley, 1999. Это самое полное и подробное руководство по рефакторингу содержит детальное обсуждение многих конкретных видов рефакторинга, упомя- нутых в этой главе, а также других видов, которых я не касался. Фаулер привел много примеров пошагового выполнения каждого вида рефакторинга.
Ключевые моменты
쐽
Изменения программы неизбежны как во время первоначальной разработки,
так и после выпуска первой версии.
쐽
Изменения могут приводить как к улучшению, так и к ухудшению ПО. Главное
Правило Эволюции ПО заключается в том, что при эволюции кода внутрен- нее качество программы должно повышаться.
쐽
Одним из условий успешности рефакторинга является пристальное внимание к многочисленным предупреждающим знакам — «запахам», указывающим на необходимость рефакторинга.
쐽
Другое условие — изучение многих конкретных видов рефакторинга.
쐽
Заключительным условием успешности рефакторинга является следование стратегии безопасного рефакторинга. Одни подходы к рефакторингу лучше,
а другие хуже.
쐽
Рефакторинг во время разработки — самая благоприятная возможность улуч- шения программы и внесения в нее всех изменений, которые вам так или иначе захочется внести позднее. Используйте эту возможность!
http://cc2e.com/2464
572
ЧАСТЬ V Усовершенствование кода
Г Л А В А 2 5
Стратегии
оптимизации кода
Содержание
쐽
25.1. Общее обсуждение производительности ПО
쐽
25.2. Введение в оптимизацию кода
쐽
25.3. Где искать жир и патоку?
쐽
25.4. Оценка производительности
쐽
25.5. Итерация
쐽
25.6. Подход к оптимизации кода: резюме
Связанные темы
쐽
Методики оптимизации кода: глава 26
쐽
Архитектура ПО: раздел 3.5
В этой главе обсуждается исторически противоречивая проблема — повышение производительности кода. В 1960-х годах ресурсы компьютеров были крайне ограниченны, поэтому эффективность их использования была вопросом перво- степенной важности. По мере роста производительности компьютеров в 70-х программисты начали понимать, насколько упор на производительность вредит удобочитаемости и легкости сопровождения кода, и оптимизация кода отошла на задний план. Вместе с микрокомпьютерной революцией, свидетелями которой мы стали в 80-х, проблема эффективного использования ресурсов вернулась, но в 90-х ее важность постепенно уменьшилась. В 2000-х мы опять столкнулись с этой про- блемой, только теперь она связана с ограниченной памятью мобильных телефо- нов, карманных ПК и подобных устройств, а также со временем выполнения ин- терпретируемого кода.
Проблемы с производительностью можно решать на двух уровнях: стратегическом и тактическом. В этой главе рассматриваются стратегические вопросы произво- дительности: мы выясним, что такое производительность, насколько она важна,
и обсудим общий подход к ее повышению. Если стратегии достижения нужной производительности вам уже хорошо известны и вы хотите узнать конкретные http://cc2e.com/2578
ГЛАВА 25 Стратегии оптимизации кода
573
методики ее повышения на уровне кода, можете перейти к главе 26. Однако прежде чем приступать к серьезной работе над повышением производительности, хотя бы просмотрите эту главу, чтобы не потратить время на оптимизацию кода тог- да, когда следовало бы заняться чем-то другим.
25.1. Общее обсуждение производительности ПО
Оптимизация кода — лишь один из способов повышения производительности программы. Часто можно найти другие способы, обеспечивающие большее повы- шение производительности за меньшее время и с меньшим вредом для кода.
Характеристики качества
и производительность
Некоторые люди смотрят на мир через розовые очки. Про- граммисты склонны воспринимать мир через кодовые очки.
Мы полагаем, что чем лучше будет наш код, тем сильнее наше
ПО понравится клиентам.
Эта точка зрения верна лишь отчасти. Пользователей боль- ше интересуют явные характеристики программы, а не ка- чество кода. Производительность обычно привлекает их внимание, только когда она сказывается на их работе. Боль- шее значение для пользователей имеет не грубая производительность приложе- ния, а объем информации, который оно позволяет обработать за конкретный срок,
а также такие факторы, как своевременное получение программы, ясный пользо- вательский интерфейс и предотвращение простоев.
Приведу пример. Я делаю цифровой камерой минимум 50 снимков в неделю. Чтобы скопировать снимки на компьютер при помощи ПО, поставляемого с камерой, я должен выбрать каждый снимок по очереди, причем в окне программы отобра- жаются только 6 снимков сразу. В результате копирование 50 изображений пре- вращается в долгий и нудный процесс, требующий десятков щелчков и массы переключений между окнами. Устав от всего этого, я купил карту памяти, подклю- чаемую прямо к компьютеру и воспринимаемую им как диск. Теперь для копиро- вания изображений на диск компьютера я могу использовать Проводник Windows.
Я делаю пару щелчков, нажимаю Ctrl+A и перетаскиваю все файлы в нужное мес- то. Меня не волнует, передает ли карта памяти каждый файл вдвое медленнее или быстрее, чем другое ПО, потому что сейчас я могу обработать больший объем информации за меньшее время. Каким бы быстрым или медленным ни был код драйвера карты памяти, его производительность выше.
Производительность только косвенно связана с быстродействием кода.
Чем больше вы работаете над скоростью кода, тем меньше внимания уделяете другим характеристикам его качества. Не приносите их в жер- тву быстродействию. Стремление к повышению быстродействия может снизить общую производительность программы, а не повысить ее.
Во имя эффективности — при- чем достигается она далеко не всегда — совершается больше компьютерных грехов, чем по любой другой причине, включая банальную глупость.
У. А. Вульф (W. A. Wulf)
574
ЧАСТЬ V Усовершенствование кода
Производительность и оптимизация кода
Решив, что эффективность кода — будь то его быстродействие или объем — дол- жна быть приоритетом, не торопитесь улучшать быстродействие или объем на уровне кода, а рассмотрите несколько вариантов. Подумайте об эффективности в контексте:
쐽
требований к программе;
쐽
проекта программы;
쐽
проектов классов и методов;
쐽
взаимодействия программы с ОС;
쐽
компиляции кода;
쐽
оборудования;
쐽
оптимизации кода.
Требования к программе
Высокая производительность считается требованием гораздо чаще, чем на самом деле им является. Барри Бом рассказывает, что при разработке одной системы в компании TRW сначала решили, что время реакции системы не должно превы- шать 1 секунды. Это требование привело к разработке очень сложного проекта,
на реализацию которого пришлось бы потратить примерно 100 млн долларов. Даль- нейший анализ показал, что в 90% случаев пользователей устроит время реакции,
равное 4 секундам. Изменение требования позволило снизить общую стоимость системы примерно на 70 млн долларов (Boehm, 2000b).
Прежде чем тратить время на решение проблемы с производительностью, убеди- тесь, что она действительно требует решения.
Проект программы
Проект программы определяет ее основные черты — глав- ным образом, способ ее разделения на классы. Проект мо- жет как облегчить, так и затруднить создание высокопро- изводительной системы.
Например, при высокоуровневом проектировании одной реальной программы сбора и обработки данных в качестве ключевого атрибута была определена пропускная способность обработки резуль- татов измерений. Каждое измерение включало определение значения электриче- ской величины, калибровку значения, масштабирование значения и преобразо- вание исходных единиц измерения (таких как милливольты) в единицы прикладной области (такие как градусы Цельсия).
Если бы при высокоуровневом проектировании программисты не оценили все факторы риска, им в итоге пришлось бы оптимизировать алгоритмы вычисления многочленов 13 степени, т. е. многочленов, содержащих 14 переменных с макси- мальной степенью 13. Вместо этого они решили проблему, выбрав другое обору- дование и разработав высокоуровневый проект, предусматривающий использо- вание десятков многочленов 3 степени. Оптимизировав код, они вряд ли получи- ли бы нужные результаты. Это пример проблемы, которую нужно было решать на уровне проектирования.
Перекрестная ссылка Проекти- рование высокопроизводитель- ных программ рассматривается в работах, указанных в разде- ле «Дополнительные ресурсы»
в конце главы.
1 ... 66 67 68 69 70 71 72 73 ... 104