понедельник, 4 января 2010 г.

Рефакторинг. Улучшение существующего кода. Часть 2

Refactoring

Обещанное продолжение цитат из замечательной книги Мартина Фаулера “Рефакторинг. Улучшение существующего кода”.

 

 

 

 

 

 

Если что-то плохо пахнет, это что-то надо поменять
                                 - Мнение бабушки Бек, высказанное
        при обсуждении проблем детского воспитания
Глава 3. Код с душком

Увидев одинаковые структуры кода в нескольких местах, можно быть уверенным, что если удастся их объединить, программа от этого только выиграет
Глава 3. Дублирование кода

Мы придерживаемся эвристического правила, гласящего, что если ощущается необходимость что-то прокомментировать, надо написать метод.
Глава 3. Длинный метод.

Весь смысл объектов в том, что они позволяют хранить данные вместе с процедурами их обработки. Классический пример дурного запаха - метод, который больше интересуется не тем классом, в котором он находится, а каким-то другим. Чаще всего предметом зависти являются данные. Не счесть случаев, когда мы сталкиваемся с методом, вызывающим полдюжины методов доступа к данным другого объекта, чтобы вычислить некоторое значение. К счастью, лечение здесь очевидно: метод явно напрашивается на перевод в другое место.
Глава 3. Завистливые функции

Брайан Фут (Brian Foote) предложил название "теоретическая общность" (speculative generality) для запаха, к которому мы очень чувствительны. Он возникает, когда говорят о том, что в будущем, наверное, потребуется возможность делать такие вещи, и хотят обеспечить набор механизмов для работы с вещами, которые не нужны. То, что получается в результате, труднее понимать и сопровождать. Если бы все эти механизмы использовались, их наличие было бы оправдано, в противном случае они только мешают, поэтому избавляйтесь от них.
Глава 3. Теоретическая общность

Цепочки сообщений появляются, когда клиент запрашивает у одного объекта другой, у которого клиент запрашивает еще один объект, у которого клиент запрашивает еще один объект и т.д. Это может выглядеть как длинный ряд методов getThis или последовательность временных переменных. Такие последовательности вызовов означают, что клиент связан с навигацией по структуре классов. Любые изменения промежуточных связей означают необходимость модификации клиента.
Глава 3. Цепочки сообщений

Почувствовав потребность написать комментарий, попробуйте сначала изменить структуру кода так, чтобы любые комментарии стали излишними.
Глава 3. Комментарии

Делайте все тесты полностью автоматическими, так чтобы они проверяли собственные результаты
Глава 4. Ценность самотестирующегося кода

Получив сообщение об ошибке, начните с создания теста модуля, показывающего эту ошибку.
Глава 4. Тесты модулей и функциональные тесты

Тестирование приносит ощутимую пользу, даже если осуществляется в небольшом объеме. Ключ к проблеме в том, чтобы тестировать те области, возможность ошибок в которых вызывает наибольшее беспокойство. При таком подходе затраты на тестирование приносят максимальную выгоду.
Глава 4. Добавление новых тестов

Лучше написать и выполнить неполные тесты, чем не выполнить полные тесты
Глава 4. Добавление новых тестов

Опасение по поводу того, что тестирование не выявит все ошибки, не должно помешать написанию тестов, которые выявят большинство ошибок.
Глава 4. Добавление новых тестов

Всегда есть риск что-то пропустить, но лучше потратить разумное время, чтобы выявить большинство ошибок, чем потратить вечность, пытаясь найти их все.
Глава 4. Добавление новых тестов

Маленькие методы действительно полезны, если выбирать для них хорошие имена. Иногда меня спрашивают, какой длины должно быть имя метода. Думаю, важна не длина, а семантическое расстояние между именем метода и телом метода. Если выделение метода делает код более понятным, выполните его, даже если имя метода окажется длиннее, чем выделенный код.
Глава 6. Выделение метода. Мотивировка.

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

Когда код имеет четкую структуру, часто находятся более мощные оптимизирующие решения, которые без рефакторинга остались бы незамеченными.
Глава 6. Замена временной переменной вызовом метода. Техника.

Все переменные, выполняющие несколько функций, должны быть заменены отдельной переменной для каждой из этих функций. Использование одной и той же переменной для решения разных задач очень затрудняет чтение кода.
Глава 6. Расщепление временной переменной. Мотивировка.

Я никогда не пробовал спать на потолке. Говорят, есть несколько способов. Наверняка одни из них легче, чем другие. С алгоритмами то же самое. Если обнаруживается более понятный способ сделать что-либо, следует заменить сложный способ простым.
Глава 6. Замещение алгоритма. Мотивировка.

Разумное и правильное проектное решение через неделю может оказаться неправильным. Но проблема не в этом, а в том, чтобы не оставить это без внимания.
Глава 7. Перемещение объекта. Мотивировка


Одним из ключевых свойств объектов является инкапсуляция. Инкапсуляция означает, что объектам приходится меньше знать о других частях системы. В результате при модификации других частей об этом требуется сообщить меньшему числу объектов, что упрощает внесение изменений.
Глава 7. Сокрытие делегирования. Мотивировка.

Важно внести ясность в смысл слова неизменяемый (immutable). Если есть класс, представляющий денежную сумму и содержащий тип валюты и величину, то обычно это объект с неизменяемым значением. Это не значит, что ваша зарплата не может измениться. Это значит, что для изменения зарплаты необходимо заменить существующий объект денежной суммы другим объектом денежной суммы, а не изменять значение в существующем объекте. Связь может измениться, но сам объект денежной суммы не изменяется.
Глава 8. Замена ссылки значением. Мотивировка.

В хорошо организованной многоуровневой системе код, обрабатывающий интерфейс пользователя, отделен от кода, обрабатывающего бизнес-логику. Это делается по нескольким причинам. Может потребоваться несколько различных интерфейсов пользователя для одинаковой бизнес-логики; интерфейс пользователя становится слишком сложным, если выполняет обе функции; сопровождать и развивать объекты предметной области проще, если они отделены от GUI; с разными частями приложения могут иметь дело разные разработчики.
Глава 8. Дублирование видимых данных. Мотивировка.

Одна точка входа обеспечивается современными языками, а в правиле одной точки выхода на самом деле пользы нет. Ясность - главный принцип: если метод понятнее, когда в нем одна точка выхода, сделайте ее единственной, в противном случае не стремитесь к этому.
Глава 9. Замена вложенных условных операторов граничным оператором. Мотивировка.

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

Преимущество исключительных ситуаций в том, что они четко отделяют нормальную обработку от обработки ошибок. Благодаря этому облегчается понимание программ, а создание понятных программ, как, я надеюсь, вы теперь верите, это достоинство, которое уступает только благочестию.
Глава 10. Замена кода ошибки исключительной ситуацией. Мотивировка.

Ральф Джонсон преподал мне важный урок, касающийся исследований: когда кто-то (рецензент статьи, участник конференции) заявляет, что он не понимает, или просто "не врубается", это наша вина. Наша обязанность постараться развить и донести свои идеи.
Глава 13. Проверка в реальных условиях

Это типичная дилемма исследователя, когда современное состояние науки опережает современное состояние практики.
Глава 13. Проверка в реальных условиях

Рефакторинг это ритм, а не отдельные ноты.
Как узнать, что вы действительно начали его понимать? Вы узнаете об этом, когда на вас снизойдет спокойствие. Когда вы почувствуете абсолютную уверенность, что как бы ни был закручен код, который вам достался, вы можете сделать его лучше, настолько лучше, чтобы развивать его дальше.
Глава 15. Складывая все вместе

Крупный рефакторинг - это способ навлечь на себя катастрофу. Каким бы ужасным ни выглядел беспорядок, приучите себя ограничиваться краями проблемы.
Глава 15. Складывая все вместе

Все цитаты из книги Мартина Фаулера “Рефакторинг. Улучшение существующего кода”.

Часть 1

Часть 2

4 комментария:

  1. А может делать выпуски покороче!?! Когда такие длинные посты рождаются, они как-то тяжелее воспринимаются.
    Может сделать посты почаще, но покороче!?!

    а) во первых проект мне жутко нравится, поэтому в любом случае СПАСИБО автору.

    б) понимаю, что вероятно посты уходят в меру готовности. Но может просто завести систему черновиков и уже опубликованных постов? Это вроде как позволит также эффективно развивать цитатник, т.к. вроде "изнутри" работа будет выглядеть почти столь же монолитной. А сами посты будут покороче.

    в) Каждая такая цитата это большой предмет для размышления и может быть дискуссий. А когда в одном посте столь много "мудрости", то воспринимать их в таком количестве телеграфным стилем тяжеловато. Опять же, полагаю, когда натыкаешься на такие цитаты в литературе, они не столь мгновенно "укладываются", "утрясаются" в голове. Требуется какое-то время на осмысление...

    ЗЫ: все безусловное и безоговорочное ИМХО, и спасибо за цитатник. Думаю, многим пригодится. Кто читал - перетряхнуть мысли, подумать в новом свете. Тем кто нет - почувствовать стилистику конкретной книги.

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

    Я могу разбивать цитаты, например, по главам. Разные посты будут разного размера, но не более 6-7 цитат. Может так?
    Либо просто, взяться за правило, чтобы в одном посте было не более, например, 5-7 цитат?
    Как думаете?

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

    ОтветитьУдалить
  3. Лично мне кажется, что наиболее логично было бы делать один пост для одной книги. Даже если цитат оказывается очень много. Зато они все в одном месте. ИМХО, это полезнее. Если мне, к примеру, потребуется найти нужную мне цитату из Рефакторинга Фаулера, я знаю какой пост смотреть.

    Разбивание цитат по количеству или по главам кажется мне не очень удобным.

    Хотя, конечно, смотря для каких целей. Для плодотворной горячей дискуссии, как мне кажется, цитаты лучше публиковать по одной. Что-то типа: "Уважаемая публика, предлагаю обсудить зело мудрую фразу товарища Т" и т.д.

    Если предполагается что-то вроде цитатохранилища с не очень горячим обсуждением, то лучше, наверно, публиковать цитаты скопом для целой книги.

    ОтветитьУдалить
  4. 2Тимур: спасибо за цитату из главы 7. Перемещение поля. Мотивировка. СУПЕР!

    2Тимур: мда... с форматом получается беда. Здесь всего три мнения и они очень сильно отличаются.
    Carc считает, что посты слишком длинные, ты думаешь, что можно все объединить в один пост, а я занимаю промежуточную сторону:))

    Главная мысль блога, не бурное обсуждение (для этого должна быть большая аудитория), хотя если это и начнется я против не буду, даже наоборот. Но и одно сообщение на всю книгу меня смущает тем, что человек просто не осилит чтение такого поста.

    Как бы я использовал такой блог: подписан на него через RSS, увидел новое сообщение, почитал, поторчал и переключился на другую задачу. Потом опять глянул один пост, почитал, _много_думал_:), переключился на что-то другое:)

    Кроме того, внизу каждого сообщения можно найти все сообщения по конкретной книге...
    Ну, и еще, можно ставить тэги с названием книг, тогда вообще эта задача пропадает, т.к. ты тыкаешь в облако тегов и получаешь все цитаты из этой книги. Хотя в этом случае ссылки на все цитаты книги будет лишним (будет слишком много места занимать).
    Только и с этим проблема, тегов будет слишком много:(

    ОтветитьУдалить