Создание, анализ ирефакторинг
Скачать 3.16 Mb.
|
18 Предисловие спустившегося с небес . Простота этих проявлений не означает их примитивности и даже не свидетельствует об их легкости . Тем не менее из них возникает величие и, более того, — красота любого человеческого начинания . Забыть о них значит не быть человеком в полной мере . Конечно, я по-прежнему выступаю за широту мышления и особенно за ценность архитектурных подходов, корни которых уходят в глубокое знание предметной области и удобство использования программных продуктов . Книга написана не об этом, или, по крайней мере, в ней эта тема не рассматривается напрямую . Она несет более тонкий посыл, глубину которого не стоит недооценивать . Она соответствует текущим мировоззрениям настоящих программистов — таких, как Питер Соммерлад (Peter Sommerlad), Кевлин Хенни (Kevlin Henney) и Джован- ни Аспрони (Giovanni Asproni) . «Код есть архитектура» и «простой код» — так звучат их мантры . Хотя мы не должны забывать, что интерфейс и есть программа и что его структурные элементы несут много информации о структуре програм- мы, очень важно помнить, что архитектура живет в коде . И если пераработка в производственной метафоре ведет к затратам, переработка в архитектурной метафоре ведет к повышению ценности . Рассматривайте свой код как красивое воплощение благородных усилий по проектированию — как процесса, а не как статической конечной точки . Архитектурные метрики привязки и связности проявляются именно в коде . Если вы послушаете, как Ларри Константайн (Larry Constantine) описывает привязку и связность, он говорит о них в контексте кода, а не величественных абстрактных концепций, которые обычно встречаются в UML . Ричард Гэбриел (Richard Gabriel) в своем эссе «Abstraction Descant» утверждает, что абстракция — зло . Так вот, код — это антизло, а чистый код, ве- роятно, имеет божественную природу . Возвращаясь к своему примеру с коробочкой Ga-Jol, подчеркну один важный мо- мент: датская народная мудрость рекомендует нам не только обращать внимание на мелочи, но и быть честными в мелочах . Это означает честность в коде, чест- ность с коллегами и, что самое важное, — честность перед самим собой по поводу состояния вашего кода . Действительно ли мы сделали все возможное для того, чтобы «оставить место лагеря чище, чем было до нашего прихода»? Переработа- ли ли свой код перед тем, как сдавать его? Эти проблемы лежат в самом сердце системы ценностей Agile . Методология Scrum указывает, чтобы переработка кода должна стать частью концепции «готовности» . Ни архитектура, ни чистый код не требуют от нас совершенства — просто будьте честны и делайте все, что можете . Человеку свойственно ошибаться; небесам свойственно прощать . В методологии Scrum все тайное становится явным . Мы выставляем напоказ свое грязное белье . Мы честно демонстрируем состояние нашего кода, а ведь код никогда не бывает идеальным . Мы становимся более человечными и приближаемая к величию в мелочах . В нашей профессии нам отчаянно нужна вся помощь, которую мы можем полу- чить . Если чистый пол в магазине сокращает вероятность несчастных случаев, а аккуратно разложенные инструменты повышают производительность, то я обе- 18 Предисловие 19 ими руками «за» . Что касается этой книги, то она является лучшим практическим применением принципов Lean в области разработки программного обеспечения, которое я когда-либо видел в печатном виде . Впрочем, я иного и не ожидал от этой небольшой группы мыслящих личностей, которые в течение многих лет стремятся не только узнать что-то новое, но и делятся своими знаниями с нами в книгах, одну из которых вы сейчас держите в руках . Мир стал чуть более со- вершенным, чем был до того момента, когда Дядюшка Боб прислал мне рукопись . Завершая свои высокопарные размышления, я отправляюсь наводить порядок на своем столе . Джеймс О. Коплин Мёрруп, Дания 19 Введение С любезного разрешения Тома Холверда (Thom Holwerda) (http://www.osnews.com/story/19266/WTFs_m) Какая из двух дверей характерна для вашего кода? Какая дверь характерна для вашей группы или компании? Почему вы попали именно в эту комнату? В ней идет нормальный анализ кода или сразу же после выпуска программы обнару- жился целый поток ужасных ошибок? Отладка идет в панике, вы просматриваете код, который, как считалось, уже работает? Клиенты уходят от вас целыми тол- пами, а начальство дышит в затылок? Как оказаться за правильной дверью, когда дела пойдут плохо? Ответ: профессионализм . 20 Введение 21 Профессионализм имеет две составляющие: знания и практический опыт . Вы должны узнать принципы, паттерны, приемы и эвристические правила, известные каждому профессионалу, а также «втереть» полученные знания в свои пальцы, глаза и внутренности усердной работой и практикой . Я могу объяснить вам физику езды на велосипеде . В самом деле, классическая физика относительно прямолинейна . Сила тяжести, сила трения, ротационный момент, центр тяжести и т . д . — все это можно описать менее чем на одной страни- це уравнений . Этими формулами я докажу вам, что езда на велосипеде возможна, и предоставлю всю необходимую для этого информацию . Но когда вы впервые заберетесь на велосипед, вы все равно неизбежно упадете . С программированием дело обстоит точно так же . Конечно, мы могли бы записать все «хорошие» принципы чистого кода, а потом доверить вам всю практическую работу (другими словами, позволить вам упасть, забравшись на велосипед), но какие бы из нас тогда были учителя? Нет . В этой книге мы пойдем по другому пути . Умение писать чистый код — тяжелая работа . Она не ограничивается знанием паттернов и принципов . Над кодом необходимо попотеть . Необходимо пытаться и терпеть неудачи . Необходимо наблюдать за тем, как другие пытаются и терпят неудачи . Необходимо видеть, как они спотыкаются и возвращаются к началу; как мучительно принимаются решения и какую цену приходится платить за не- верный выбор . Приготовьтесь основательно потрудиться во время чтения книги . Перед вами не «легкое чтиво», которое можно проглотить в самолете и перевернуть послед- нюю страницу перед посадкой . Книга заставит вас потрудиться, и потрудиться усердно . Какая работа вам предстоит? Вы будете читать код — много кода . И вам придется как следует подумать, что в этом коде правильно, а что нет . Вы будете наблюдать за тем, как мы разбираем эти модули, а потом собираем заново . Это потребует немало времени и усилий; но мы считаем, что результат того стоит . Книга разделена на три части . В первых нескольких главах излагаются принципы, паттерны и приемы написания чистого кода . В них приводится довольно солид- ный объем кода, и читать их будет непросто . Весь этот материал подготовит вас ко второй части . Если вы отложите книгу после первой части — всего хорошего! Во второй части книги трудиться придется еще больше . Она состоит из несколь- ких практических сценариев нарастающей сложности . Каждый сценарий пред- ставляет собой упражнение по чистке кода — или преобразовании проблемного кода в код с меньшим количеством проблем . Чтобы усвоить материал этой части, необходимо основательно потрудиться . Вам придется переключаться туда-сюда между текстом и листингами . Вам придется анализировать и разбирать код, с ко- торым мы работаем, и осознать причину каждого вносимого изменения . Выделите на это время, потому что работа займет не один день . Третья часть книги — концентрированное выражение ее сути . Она состоит из одной главы с перечнем эвристических правил и «запахов кода», собранных во 21 22 Введение время анализа . В ходе очистки кода в практических сценариях мы документиро- вали причину каждого выполняемого действия в виде эвристического правила или «запаха» . Мы пытались понять нашу собственную реакцию на код в процессе его чтения и изменения; старались объяснить, почему мы чувствовали то, что чув- ствовали, или делали то, что делали . Результат представляет собой базу знаний, описывающую наш путь мышления в процессе чтения, написания и чистки кода . Впрочем, без тщательного чтения всех практических сценариев из второй части книги пользы от базы знаний будет немного . В этих сценариях мы тщательно пометили каждое вносимое изменение ссылкой на соответствующее эвристиче- ское правило . Ссылки заключаются в квадратные скобки и выглядят примерно так: [H22] . Это позволяет читателю видеть контекст, в котором применяются эвристики! Главная ценность заключается даже не в самих эвристиках, а связях между ними и конкретными решениями, принимаемыми в ходе чистки кода практических сценариев . Чтобы помочь вам отслеживать эти связи, мы разместили в конце книги список перекрестных ссылок . В нем приведены номера страниц всех ссылок . По этому списку можно найти каждое место, в котором применялась та или иная эври- стика . Если вы прочитаете первую и третью часть, пропустив анализ практических сценариев, — считайте, что вы прочитали еще одну «легкую» книгу о написании качественного кода . Но если вы потратите время на проработку всех сценариев, проследите за каждым крошечным шагом, за каждым решением, если вы по- ставите себя на наше место и заставите себя думать в том же направлении, то ваше понимание этих принципов, паттернов, приемов и эвристик значительно углубится . Знания уже не будут «внешними» . Они проникнут в ваши пальцы, глаза и сердце . Они станут частью вашей личности — как велосипед становится продолжением вашего тела, когда вы научитесь на нем ездить . Благодарности Я благодарю двух художников, Дженнифер Конке ( Jeniffer Kohnke) и Анджелу Брукс (Angela Brooks) . Дженнифер создала отличные остроумные рисунки в на- чале каждой главы, а также нарисовала портреты Кента Бека, Уорда Каннингема, Бьёрна Страуструпа, Рона Джеффриса, Грэди Буча, Дэйва Томаса, Майкла Физерса… и меня . Анджела занималась рисунками, поясняющими материал внутри глав . За про- шедшие годы она подготовила немало иллюстраций для моих книг, в том числе для книги «Agile Software Develpment: Principles, Patterns, and Practices» . Кроме того, она мой первенец, и я ей горжусь . 22 Чистый код Вы читаете эту книгу по двум причинам . Во-первых, вы программист . Во-вторых, вы хотите повысить свою квалификацию как программиста . Отлично . Хороших программистов не хватает . Эта книга посвящена хорошему программированию . Она полна реальных при- меров кода . Мы будем рассматривать код с направлений: сверху вниз, снизу 1 23 24 Глава 1 . Чистый код вверх, и даже изнутри . К последней странице книги вы узнаете много нового о коде . Более того, вы научитесь отличать хороший код от плохого . Вы узнаете, как писать хороший код и как преобразовать плохой код в хороший . Да будет код Возможно, кто-то скажет, что книга о коде отстала от времени — код сейчас уже не так актуален; вместо него внимание следует направить на модели и требова- ния . Нам даже доводилось слышать мнение, что код как таковой скоро переста- нет существовать . Что скоро весь код будет генерироваться, а не писаться вруч- ную . Что программисты станут попросту не нужны, потому что бизнесмены бу- дут генерировать программы по спецификациям . Ерунда! Код никогда не исчезнет, потому что код представляет подробности тре- бований . На определенном уровне эти подробности невозможно игнорировать или абстрагировать; их приходится определять . А когда требования определяются настолько подробно, чтобы они могли быть выполнены компьютером, это и есть программирование . А их определение есть код . Вероятно, уровень абстракции наших языков продолжит расти . Я также ожидаю, что количество предметно-ориентированных языков продолжит расти . И это хорошо . Но код от этого существовать не перестанет . В самом деле, все опреде- ления, написанные на этих высокоуровневых, предметно-ориентированных языках, станут кодом! И этот код должен быть достаточно компактным, точным, формальным и подробным, чтобы компьютер мог понять и выполнить его . Люди, полагающие, что код когда-нибудь исчезнет, напоминают математиков, которые надеются когда-нибудь обнаружить неформальную математическую дисциплину . Они надеются, что когда-нибудь будут построены машины, кото- рые будут делать то, что мы хотим, а не то, что мы приказываем сделать . Такие машины должны понимать нас настолько хорошо, чтобы преобразовать набор нечетких потребностей в идеально выполняемые программы, точно отвечающие этим потребностям . Но этого никогда не произойдет . Даже люди, со всей их интуицией и изобре- тательностью, не способны создавать успешные системы на основе туманных представлений своих клиентов . Если дисциплина определения требований нас чему-то научила, так это тому, что четко определенные требования так же формальны, как сам код, и могут использоваться как исполняемые тесты этого кода! В сущности, код представляет собой язык, на котором в конечном итоге выра- жаются потребности . Мы можем создавать языки, близкие к потребностям . Мы можем создавать инструменты, помогающие нам обрабатывать и собирать эти потребности в формальные структуры . Но необходимая точность никогда не исчезнет — а следовательно, код останется всегда . 24 Да будет код 25 Плохой код Недавно я читал предисловие к книге Кента Бека «Implementation Patterns» [Beck07] . Автор гово- рит: «…эта книга базируется на довольно непроч- ной предпосылке: что хороший код важен…» Не- прочная предпосылка? Не согласен! На мой взгляд, эта предпосылка является одной из самых мощных, основополагающих и многогранных положений нашего ремесла (и я думаю, что Кен- ту это известно) . Мы знаем, что хороший код важен, потому что нам приходилось так долго мириться с его отсутствием . Одна компания в конце 80-х годов написала приложение-бестселлер . Приложение стало чрез- вычайно популярным, многие профессионалы покупали и использовали его . Но потом циклы выпуска новых версий стали затягиваться . Ошиб- ки не исправлялись между версиями . Время загрузки росло, а сбои происходили все чаще . Помню тот день, когда я в раздражении закрыл этот продукт и никогда не запускал его . Вскоре эта компания разорилась . Два десятилетия спустя я встретил одного из работников той компании и спро- сил его, что же произошло . Ответ подтвердил мои опасения . Они торопились с выпуском продукта на рынок и не обращали внимания на качество кода . С до- бавлением новых возможностей код становился все хуже и хуже, пока в какой-то момент не вышел из-под контроля . Плохой код привел к краху компании . Плохой код когда-нибудь мешал вашей работе? Любой сколько-нибудь опыт- ный программист неоднократно попадал в подобную ситуацию . Мы продираем- ся через плохой код . Мы вязнем в хитросплетении ветвей, попадаем в скрытые ловушки . Мы с трудом прокладываем путь, надеясь получить хоть какую-нибудь подсказку, что же происходит в коде; но не видим вокруг себя ничего, кроме но- вых залежей невразумительного кода . Конечно, плохой код мешал вашей работе . Почему же вы писали его? Пытались поскорее решить задачу? Торопились? Возможно . А может быть, вам казалось, что у вас нет времени качественно выполнить свою работу; что ваше начальство будет недовольно, если вы потратите время на чистку своего кода . А может, вы устали работать над программой и вам хотелось поскорее избавиться от нее . А мо- жет, вы посмотрели на список запланированных изменений и поняли, что вам необходимо поскорее «прикрутить» этот модуль, чтобы перейти к следующему . Такое бывало с каждым . Каждый из нас смотрел на тот хаос, который он только что сотворил, и решал оставить его на завтра . Каждый с облегчением видел, что бестолковая программа работает, и решал, что рабочая мешанина — лучше, чем ничего . Каждый обещал 25 26 Глава 1 . Чистый код себе вернуться и почистить код… потом . Конечно, в те дни мы еще не знали закон Леблана: потом равносильно никогда . Расплата за хаос Если вы занимались программированием более двух-трех лет, вам наверняка до- водилось вязнуть в чужом — или в своем собственном — беспорядочном ходе . Замедление может быть весьма значительным . За какие-нибудь год-два груп- пы, очень быстро двигавшиеся вперед в самом начале проекта, начинают полз- ти со скоростью улитки . Каждое изменение, вносимое в код, нарушает рабо- ту кода в двух-трех местах . Ни одно изменение не проходит тривиально . Для каждого дополнения или модификации системы необходимо «понимать» все хитро сплетения кода — чтобы в программе их стало еще больше . Со временем неразбериха разрастается настолько, что справиться с ней уже не удается . Вы- хода просто нет . По мере накопления хаоса в коде производительность группы начинает снижать- ся, асимптотически приближаясь к нулю . В ходе снижения производительности начальство делает единственное, что оно может сделать: подключает к проекту новых работников в надежде повысить производительность . Но новички ничего не понимают в архитектуре системы . Они не знают, какие изменения соот- ветствуют намерениям проектировщика, а какие им противоречат . Более того, они — и все остальные участники группы — находятся под страшным давлением со стороны начальства . В спешке они работают все небрежнее, отчего произво- дительность только продолжает падать (рис . 1 .1) . Рис . 1 .1 . Зависимость производительности от времени Грандиозная переработка В конечном итоге группа устраивает бунт . Она сообщает начальству, что не может продолжать разработку отвратительной кодовой базы, и требует переработки архитектуры . Начальство не хочет тратить ресурсы на полную переработку про- екта, но не может отрицать, что производительность просто ужасна . Со временем 26 Расплата за хаос 27 начальство поддается на требования разработчиков и дает разрешение на про- ведение грандиозной переработки . Набирается новая «ударная группа» . Все хотят в ней участвовать, потому что проект начинается «с нуля» . Разработчики будут строить «на пустом месте», и со здадут нечто воистину прекрасное . Но в «ударную группу» отбирают толь- ко самых лучших и умных . Всем остальным приходится сопровождать текущую систему . Между двумя группами начинается гонка . «Ударная группа» должна построить новую систему, которая делает то же самое, что делала старая . Более того, она должна своевременно учитывать изменения, непрерывно вносимые в старую систему . Начальство не заменяет старую систему до тех пор, пока новая система не будет полностью повторять ее функциональность . Такая гонка может продолжаться очень долго . Мне известны случаи, как она продолжалась по 10 лет . И к моменту ее завершения оказывалось, что исходный состав давно покинул «ударную группу», а текущие участники требовали пере- работать новую систему, потому что в ней творился сущий хаос . Если вы сталкивались хотя бы с некоторыми частями истории, которую я сейчас поведал, то вы уже знаете, что поддержание чистоты кода не только окупает за- траченное время; оно является делом профессионального выживания . |