Главная страница
Навигация по странице:

  • Контрольный список: отладка Методики поиска дефектов

  • Методики поиска и исправления синтаксических ошибок

  • Методики устранения дефектов

  • ГЛАВА 23

  • ЧАСТЬ V

  • 24.2. Введение в рефакторинг

  • Разумные причины выполнения рефакторинга

  • Цикл слишком велик или слишком глубоко вложен в другие циклы

  • Класс имеет плохую связность

  • Интерфейс класса не формирует согласованную абстракцию

  • Метод принимает слишком много параметров

  • Отдельные части класса изменяются независимо от других частей

  • При изменении программы требуется параллельно изменять несколько

  • Вам приходится параллельно изменять несколько иерархий наследования

  • Вам приходится параллельно изменять несколько блоков

  • Родственные элементы данных, используемые вместе, не организованы

  • Совершенный код. Совершенный код. Мастер-класс. Стив Макконнелл. Руководство по стилю программирования и конструированию по


    Скачать 5.88 Mb.
    НазваниеРуководство по стилю программирования и конструированию по
    АнкорСовершенный код
    Дата31.03.2023
    Размер5.88 Mb.
    Формат файлаpdf
    Имя файлаСовершенный код. Мастер-класс. Стив Макконнелл.pdf
    ТипРуководство
    #1028502
    страница69 из 106
    1   ...   65   66   67   68   69   70   71   72   ...   106
    ГЛАВА 23 Отладка
    547
    Отладчики
    Коммерческие отладчики непрерывно совершенствуются и могут значительно изменить ваш способ программирования. Хорошие отладчики позволяют преры#
    вать выполнение программы на конкретной строке, при достижении конкретной строки в
    n#й раз, при изменении глобальной переменной или при присвоении переменной конкретного значения. Они позволяют выполнять код строка за стро#
    кой с «перешагиванием» через методы или с их «посещением», возвращаться к началу дефектного фрагмента, а также регистрировать выполнение отдельных операторов в журнале, что похоже на разбрасывание по всей программе команд печати «Я здесь!».
    Хорошие отладчики позволяют полностью исследовать данные, в том числе струк#
    турированные и динамически выделенные. С их помощью легко просмотреть со#
    держание связного списка указателей или динамически выделенного массива. Они поддерживают типы данных, определенные пользователем. Они позволяют выпол#
    нить нерегламентированный запрос данных, присвоить им новые значения и про#
    должить выполнение программы.
    Вы можете работать с высокоуровневым языком или ассемблерным кодом, сге#
    нерированным компилятором. Если вы используете несколько языков, отладчик автоматически выводит любой фрагмент кода на соответствующем языке. Вы можете изучить цепочку вызовов методов и быстро увидеть исходный код любо#
    го метода. В среде отладчика вы можете изменять параметры программы.
    Лучшие отладчики запоминают параметры отладки (точки прерывания, отслежи#
    ваемые переменные и т. д.) каждой отдельной программы, чтобы их не нужно было задавать заново.
    Системные отладчики работают на системном, а не прикладном уровне, не влияя на выполнение отлаживаемой программы. Это важно, если вы отлаживаете про#
    грамму, чувствительную ко времени выполнения или объему доступной памяти.
    Если учесть все достоинства отладчиков, может показаться странным, что кто#то их критикует. И все же некоторые из самых уважаемых людей в мире компьютерных наук реко#
    мендуют их не использовать. Они советуют полагаться на свой ум и избегать инструментов отладки вообще. Они утверждают, что инструменты отладки — это костыли и что вы решите проблемы быстрее и лучше, размышляя о них, а не опираясь на инструменты. Они утверждают, что при по#
    иске дефектов программу нужно выполнять в уме, а не в отладчике.
    Какими бы ни были эмпирические данные, суть нападок на отладчики некоррек#
    тна. Если инструмент допускает неграмотное применение, это не значит, что от него надо отказаться. Было бы глупо запретить аспирин из#за возможности пере#
    дозировки. Риск пораниться не заставил бы вас прекратить подстригать лужайку перед домом. Любой эффективный инструмент можно использовать правильно и неправильно. Отладчик — не исключение.
    Интерактивный отладчик — ве- ликолепный пример инструмен- та, который не нужен: он поощ- ряет хакерство методом проб и ошибок, а не систематичное проектирование и позволяет непрофессионалам скрыть свою некомпетентность.
    Харлан Миллз
    (Harlan Mills)

    548
    ЧАСТЬ V Усовершенствование кода
    Отладчик не заменит грамотного рассуждения. Но иногда никакие мыс#
    ли не заменят хороший отладчик. Наиболее эффективная комбинация —
    ясный ум и хороший отладчик.
    Контрольный список: отладка
    Методики поиска дефектов
     Формулируя гипотезу, используйте все имеющиеся данные.
     Детализируйте тесты, приводящие к ошибке.
     Проверяйте код при помощи блочных тестов.
     Используйте разные доступные инструменты.
     Воспроизведите ошибку несколькими разными способами.
     Генерируйте больше данных для формулирования большего числа гипотез.
     Используйте результаты отрицательных тестов.
     Используйте «мозговой штурм» для построения нескольких гипотез.
     Составьте список подходов, которые следует попробовать.
     Сократите подозрительную область кода.
     С подозрением относитесь к классам и методам, которые содержали дефекты ранее.
     Проверьте код, который был изменен недавно.
     Расширьте подозрительный фрагмент кода.
     Выполняйте интеграцию инкрементно.
     Проверяйте наличие распространенных дефектов.
     Обсудите проблему с кем-то другим.
     Отдохните от проблемы.
     Установите сроки быстрой и грязной отладки.
     Составьте список методик грубой силы и используйте их.
    Методики поиска и исправления синтаксических ошибок
     Не полагайтесь на номера строк в сообщениях компилятора.
     Не доверяйте сообщениям компилятора.
     Не доверяйте второму сообщению компилятора.
     Разделяй и властвуй.
     Используйте редактор с проверкой синтаксиса для поиска неверно разме- щенных символов комментария и кавычек.
    Методики устранения дефектов
     Прежде чем браться за решение проблемы, поймите ее.
     Не ограничивайтесь пониманием проблемы — поймите программу.
     Подтвердите диагноз проблемы.
     Расслабьтесь.
     Сохраняйте первоначальный исходный код.
     Устраняйте проблему, а не ее симптомы.
     Изменяйте код только при наличии веских оснований.
     Вносите в код по одному изменению за раз.
     Проверяйте исправления.
     Добавляйте в набор тестов блочные тесты, приводящие к проявлению име- ющихся дефектов.
     Поищите похожие дефекты.
    http://cc2e.com/2368

    ГЛАВА 23 Отладка
    549
    Общий подход к отладке
     Рассматриваете ли вы отладку как возможность лучше изучить программу,
    ошибки, качество кода и подход к решению проблем?
     Избегаете ли вы суеверного подхода к отладке, основанного на методе проб и ошибок?
     Полагаете ли вы, что ошибки допущены именно вами?
     Используете ли вы научный метод для стабилизации несистематических ошибок?
     Используете ли вы научный метод для нахождения дефектов?
     Используете ли вы несколько методик поиска дефектов?
     Проверяете ли вы корректность исправлений?
     Анализируете ли вы предупреждения компилятора? Используете ли вы ин- струменты профилирования выполнения программы, среды тестирования, леса и интерактивные отладчики?
    Дополнительные ресурсы
    Ниже я привел список книг, посвященных отладке.
    Agans, David J.
    Debugging: The Nine Indispensable Rules for
    Finding Even the Most Elusive Software and Hardware Problems.
    Amacom, 2003. В этой книге рассматриваются общие принципы отладки, не зави#
    сящие ни от языка, ни от среды.
    Myers, Glenford J.
    The Art of Software Testing. New York, NY: John Wiley & Sons, 1979.
    Седьмая глава этой классической книги посвящена отладке.
    Allen, Eric.
    Bug Patterns In Java. Berkeley, CA: Apress, 2002. В данной книге описывает#
    ся методика отладки программ Java, концептуально очень похожая на описанную в этой главе. Как и здесь, в ней рассмотрен «Научный метод отладки», проведено различие между отладкой и тестированием и определены частые ошибки.
    Названия двух следующих книг могут навести на мысль о том, что они адресова#
    ны только разработчикам программ для Microsoft Windows и .NET, однако это не так: помимо всего прочего, в них вы найдете обсуждение отладки в целом, сове#
    ты по использованию утверждений, а также описания методик кодирования, по#
    могающих предотвращать ошибки.
    Robbins, John.
    Debugging Applications for Microsoft .NET and Microsoft Windows. Red#
    mond, WA: Microsoft Press, 2003 1
    McKay, Everett N. and Mike Woodring.
    Debugging Windows Programs: Strategies, Tools,
    and Techniques for Visual C++ Programmers. Boston, MA: Addison#Wesley, 2000.
    http://cc2e.com/2375 1
    Роббинс Дж. Отладка приложений для Microsoft .NET и Microsoft Windows. — М.: Русская Редак#
    ция, 2004. —
    Прим. перев.

    550
    ЧАСТЬ V Усовершенствование кода
    Ключевые моменты
    
    Отладка — это тот этап разработки программы, от которого зависит возмож#
    ность ее выпуска. Конечно, лучше всего вообще избегать ошибок, используя другие методики, описанные в этой книге. Однако потратить время на улучшение на#
    выков отладки все же стоит, потому что эффективность отладки, выполняемой лучшими и худшими программистами, различается минимум в 10 раз.
    
    Систематичный подход к поиску и исправлению ошибок — непременное ус#
    ловие успешности отладки. Организуйте отладку так, чтобы каждый тест при#
    ближал вас к цели. Используйте Научный Метод Отладки.
    
    Прежде чем приступать к исправлению программы, поймите суть проблемы.
    Случайные предположения о причинах ошибок и случайные исправления толь#
    ко ухудшат программу.
    
    Установите в настройках компилятора самый строгий уровень диагностики и устраняйте причины всех ошибок и предупреждений. Как вы исправите неуло#
    вимые ошибки, если будете игнорировать явные?
    
    Инструменты отладки значительно облегчают разработку ПО. Найдите их и используйте, но не забывайте, что у вас есть еще и голова.

    ГЛАВА 23 Отладка
    551
    Г Л А В А 2 4
    Рефакторинг
    Содержание
    
    24.1. Виды эволюции ПО
    
    24.2. Введение в рефакторинг
    
    24.3. Отдельные виды рефакторинга
    
    24.4. Безопасный рефакторинг
    
    24.5. Стратегии рефакторинга
    Связанные темы
    
    Советы по устранению дефектов: раздел 23.3
    
    Подход к оптимизации кода: раздел 25.6
    
    Проектирование при конструировании: глава 5
    
    Классы: глава 6
    
    Высококачественные методы: глава 7
    
    Совместное конструирование: глава 21
    
    Тестирование, выполняемое разработчиками: глава 22
    
    Области вероятных изменений: подраздел «Определите области вероятных изменений» раздела 5.3
    Миф: в начале реализации программного проекта проводит#
    ся методичная выработка требований, и составляется устой#
    чивый список аспектов ответственности программы. Про#
    ектирование соответствует требованиям и выполняется со всей тщательностью, благодаря чему кодирование от начала до конца протекает линейно: вы пишете код, тестируете его и оставляете в покое. Согласно этому мифу значительные изменения кода возможны только при сопровождении ПО, т. е. после выпуска первоначальной версии системы.
    Реальность: во время разработки первоначальной версии системы в код вносятся значительные изменения. Многие из изменений во время ко#
    дирования не менее масштабны, чем изменения, характерные для стадии сопровождения программы. В зависимости от размера проекта кодирование, от#
    ладка и блочное тестирование обычно составляют от 30 до 65% общего объема http://cc2e.com/2436
    Все удачные программы изме- няются.
    Фред Брукс (Fred Brooks)

    552
    ЧАСТЬ V Усовершенствование кода работы над проектом (см. главу 27). Если бы кодирование и блочное тестирова#
    ние были линейными однократными процессами, они составляли бы не более 20–
    30% общего объема работы. Однако даже в хорошо управляемых проектах требо#
    вания изменяются примерно на 1–4% в месяц (Jones, 2000). Изменения требова#
    ний неизбежно приводят к изменениям кода, порой весьма существенным.
    Другая реальность: современные методики разработки предполагают больший масштаб изменений кода во время конструирования. Целью более старых методик (достигалась она или нет — другой вопрос) было предотвращение изменений кода. Современные подходы снижают предсказуемость кодирования. Они в большей степени ориентированы на код, поэтому вы вполне можете ожидать, что на протяжении жизненного цикла проекта код будет изме#
    няться сильнее, чем когда бы то ни было.
    24.1. Виды эволюции ПО
    Эволюция ПО похожа на биологическую эволюцию тем, что лишь немногие му#
    тации выгодны. При здоровой эволюции кода его развитие напоминает превра#
    щение обезьян в неандертальцев, а неандертальцев — в программистов, которые,
    как известно, являются самыми высокоразвитыми существами на Земле. Однако иногда эволюционные силы проявляют себя иным образом, ввергая программу в спираль деградации.
    Главное различие между видами эволюции программы в том, повышает#
    ся или снижается ее качество в результате изменений. Если при исправ#
    лении ошибок вы опираетесь на суеверия и устраняете лишь симптомы проблем, качество снижается. Если же вы рассматриваете изменения как возмож#
    ности улучшить первоначальный проект программы, — повышается. При сниже#
    нии качества программа начинает походить на молчащую канарейку в шахте, о которой я уже говорил. Это знак того, что программа развивается в неверном на#
    правлении.
    Характер эволюции программы зависит и от того, когда в нее вносятся измене#
    ния: во время конструирования или во время сопровождения. Изменения во вре#
    мя конструирования обычно вносят первоначальные разработчики, которые еще хорошо помнят код программы. Система еще не используется, поэтому програм#
    мисты испытывают давление только со стороны графика разработки, а не сотен сердитых пользователей, возмущенных неработоспособностью системы. По той же причине изменения во время конструирования можно вносить более свобод#
    но: система находится в более динамичном состоянии, а следствия ошибок ме#
    нее серьезны. Из этого следует, что во время разработки ПО эволюционирует не так, как при сопровождении.
    Философия эволюции ПО
    Слабость многих подходов к эволюции ПО объясняется тем, что она пускается на самотек. Осознав, что эволюция ПО во время его разработки — неизбежный и важный процесс и спланировав его, вы сможете извлечь из него выгоду.

    ГЛАВА 24 Рефакторинг
    553
    Эволюция заключает в себе и опасность, и возможность приближения к совершенству. При необходимости измене#
    ния кода старайтесь улучшить его, чтобы облегчить внесе#
    ние изменений в будущем. В процессе написания програм#
    мы вы всегда узнаете о ней что#то новое. Получив возмож#
    ность изменения программы, используйте то, что вы узна#
    ли, для ее улучшения. Пишите первоначальный код и его изменяйте, держа в уме дальнейшие изменения.
    Главное Правило Эволюции ПО состоит в том, что эволюция должна повышать внутреннее качество программы. О том, как этого добиться, я расскажу в следующих разделах.
    24.2. Введение в рефакторинг
    Важнейшей стратегией достижения цели Главного Правила Эволюции ПО явля#
    ется рефакторинг, который Мартин Фаулер определяет как «изменение внутрен#
    ней структуры ПО без изменения его наблюдаемого поведения, призванное об#
    легчить его понимание и удешевить модификацию» (Fowler, 1999). Слово «рефак#
    торинг» возникло из слова «факторинг», которое изначально использовал в кон#
    тексте структурного программирования Ларри Константайн, назвавший так мак#
    симально возможную декомпозицию программы на составляющие части (Yourdon and Constantine, 1979).
    Разумные причины выполнения рефакторинга
    Иногда код деградирует при сопровождении, а иногда он изначально имеет не#
    высокое качество. В обоих случаях на это — и на необходимость рефакторинга
    — указывают некоторые предупреждающие знаки, иногда называемые «запахами»
    (smells) (Fowler, 1999). Они описаны ниже.
    Код повторяется Повторение кода почти всегда говорит о неполной факто#
    ризации системы на этапе проектирования. Повторение кода заставляет парал#
    лельно изменять сразу несколько фрагментов программы и нарушает правило, ко#
    торое Эндрю Хант и Дэйв Томас назвали «принципом DRY»: Don’t Repeat Yourself
    (не повторяйтесь) (Hunt and Thomas, 2000). Думаю, лучше всех это правило сфор#
    мулировал Дэвид Парнас: «Копирование и вставка кода — следствие ошибки про#
    ектирования» (McConnell, 1998b).
    Метод слишком велик В объектно#ориентированном программировании ме#
    тоды, не умещающиеся на экране монитора, требуются редко и обычно свидетель#
    ствуют о попытке насильно втиснуть ногу структурного программирования в объектно#ориентированный ботинок.
    Одному из моих клиентов поручили разделить самый объемный метод унаследо#
    ванной системы, включающий более 12 000 строк. Приложив немалые усилия, он смог уменьшить объем этого метода только примерно до 4000 строк.
    Одним из способов улучшения системы является повышение ее модульности —
    увеличение числа хорошо определенных и удачно названных методов, успешно решающих только одну задачу. Если обстоятельства заставляют вас пересмотреть
    Не бывает кода, настолько гро- моздкого, изощренного или сложного, чтобы его нельзя было ухудшить при сопровождении.
    Джеральд Вайнберг
    (Gerald Weinberg)

    554
    ЧАСТЬ V Усовершенствование кода фрагмент кода, используйте эту возможность для проверки модульности методов,
    содержащихся в этом фрагменте. Если вам кажется, что после разделения одного метода на несколько код станет яснее, создайте дополнительные методы.
    Цикл слишком велик или слишком глубоко вложен в другие циклы Подхо#
    дящим кандидатом на преобразование в метод часто оказывается тело цикла —
    это помогает лучше факторизовать код и снизить сложность цикла.
    Класс имеет плохую связность Если класс имеет множество никак не связан#
    ных аспектов ответственности, разбейте его на несколько классов, так чтобы каж#
    дый из них получил связный набор аспектов.
    Интерфейс класса не формирует согласованную абстракцию Даже клас#
    сы, получившие при рождении связный интерфейс, могут терять первоначальную согласованность. В результате необдуманных изменений, повышающих удобство использования класса за счет целостности его интерфейса, интерфейс иногда становится монстром, не поддающимся сопровождению и не улучшающим интел#
    лектуальную управляемость программы.
    Метод принимает слишком много параметров Как правило, хорошо фак#
    торизованные программы включают много небольших хорошо определенных методов, не нуждающихся в большом числе параметров. Длинный список пара#
    метров — свидетельство того, что абстракция, формируемая интерфейсом мето#
    да, неудачна.
    Отдельные части класса изменяются независимо от других частей
    Иногда класс имеет две (или более) разных области ответственности. Если это так,
    вы заметите, что вы изменяете или одну часть класса, или другую, и лишь немно#
    гие изменения затрагивают обе части класса. Это признак того, что класс следует разделить на несколько классов в соответствии с отдельными областями ответ#
    ственности.
    При изменении программы требуется параллельно изменять несколько
    классов Мне известен один проект, в котором был составлен контрольный список где#то из 15 классов, требующих изменения при добавлении нового вида выход#
    ных данных. Если вы уже в который раз изменяете один и тот же набор классов,
    подумайте, можно ли реорганизовать код этих классов так, чтобы изменения за#
    трагивали только один класс. Опыт говорит мне, что этого идеала достичь нелег#
    ко, но стремиться к нему нужно.
    Вам приходится параллельно изменять несколько иерархий наследования
    Если при создании каждого нового подкласса одного класса вам приходится со#
    здавать подкласс другого класса, вы имеете дело с особым видом параллельного изменения. Решите эту проблему.
    Вам приходится параллельно изменять несколько блоков case В самих по себе блоках
    case ничего плохого, но, если вы параллельно изменяете похожие блоки
    case в нескольких частях программы, спросите себя, не лучше ли использовать наследование.
    Родственные элементы данных, используемые вместе, не организованы
    в классы Если вы неоднократно используете один и тот же набор элементов дан#
    ных, рассмотрите целесообразность объединения этих данных и выполняемых над ними операций в отдельный класс.

    1   ...   65   66   67   68   69   70   71   72   ...   106


    написать администратору сайта