Материал: Руководство по стилю программирования и конструированию по

Внимание! Если размещение файла нарушает Ваши авторские права, то обязательно сообщите нам
ГЛАВА 34 Основы мастерства
829
Если вы ловите себя на том, что работаете над повторяющимся кодом или вноси- те похожие изменения в несколько фрагментов, вам следует почувствовать себя
«неловко и неприятно», усомнившись в том, что управление было адекватно цен- трализовано в классах или методах. Если из-за проблем с отдельным классом вы не можете с легкостью создать тестовые леса, вы должны почувствовать сомне- ние и спросить себя, не слишком ли сильно класс сопряжен с другими классами.
Если вы не можете повторно использовать код в других программах, потому что некоторые классы слишком взаимозависимы, это также предупреждает о черес- чур сильном сопряжении классов.
Погрузившись в детали программы, обращайте внимание на предупреждающие знаки, указывающие на то, что часть проекта программы недостаточно хорошо определена для кодирования. Трудности при написании комментариев, именова- нии переменных и декомпозиции проблемы на связные классы с ясными интер- фейсами — все это говорит о том, что нужно более тщательно выполнить проек- тирование перед началом кодирования. Невыразительные имена и сложности при описании фрагментов кода лаконичными комментариями — другие признаки проблем. Если вы хорошо представляете проект программы, реализовать низко- уровневые детали будет легко.
Обращайте внимание на признаки того, что программу трудно понять. Об этом свидетельствуют любые неудобства. Если это трудно для вас, для будущих програм- мистов это окажется еще труднее. Они по достоинству оценят ваши дополнитель- ные усилия по улучшению кода. Если вы разгадываете код, а не читаете его, он слишком сложен. Если он сложен, он неверен. Сделайте его проще.
Если вы хотите воспользоваться всеми преимуществами предупреждаю- щих знаков, программируйте так, чтобы создать собственные предупреж- дения. Это полезно потому, что, даже если вам известны предупреждаю- щие знаки, их на удивление легко упустить из виду. Гленфорд Майерс исследовал исправления дефектов и обнаружил, что самой частой причиной плохого обна- ружения ошибок была простая невнимательность. Ошибки были видны в резуль- татах тестов, но программисты их не замечали (Myers, 1978b).
Программируйте так, чтобы ошибки было трудно не заметить. Примером этого может служить установка указателей в
NULL после их освобождения, чтобы их ошибочное использование вызывало безобразные проблемы. Освобожденный указатель даже после освобождения может указывать на корректную область па- мяти. Установка указателя в

NULL гарантирует, что он будет указывать на некор- ректный адрес, благодаря чему ошибку будет сложнее не заметить.
Предупреждения компилятора являются буквальными предупреждающими знаками,
которые часто упускают из виду. Если ваша программа генерирует предупрежде- ния или ошибки, устраните их. Невелика вероятность того, что вы заметите тон- кие предупреждающие знаки, если вы игнорируете те, на которых прямо написа- но «ПРЕДУПРЕЖДЕНИЕ».
Почему внимание к интеллектуальным предупреждающим знакам особенно важ- но при разработке ПО? Качество мышления, воплощаемое в программе, во мно- гом определяет качество самой программы, поэтому внимание к предупреждениям о качестве мышления напрямую влияет на итоговый продукт.

830
ЧАСТЬ VII Мастерство программирования
34.8. Итерируйте, итерируйте и итерируйте
Итерация полезна на многих этапах разработки ПО. При разработке первоначаль- ной спецификации системы вы составляете с заказчиком несколько версий тре- бований, пока не достигнете согласия. Это итеративный процесс. Гибкий процесс разработки, предусматривающий создание и поставку системы по частям, тоже итеративен. Прототипирование, имеющее целью быструю и дешевую разработку предварительных вариантов решений, — еще одна форма итерации. Итеративная выработка требований, наверное, не менее важна, чем любой другой аспект про- цесса разработки ПО. Проекты завершаются неудачей потому, что разработчики приступают к решению проблемы, не изучив альтернативных вариантов. Итера- ция позволяет лучше узнать систему перед ее созданием.
Оценки сроков при первоначальном планировании проекта могут сильно разли- чаться в зависимости от используемой методики оценки (см. главу 28). Итеративный подход дает более точную оценку, чем единственная методика.
Проектирование ПО — процесс эвристический и, как все эвристические процес- сы, допускает итеративные ревизии и улучшения. Правильность ПО обычно про- веряется, а не доказывается, а значит, оно тестируется и разрабатывается итеративно,
пока на все вопросы не будут получены правильные ответы. И высокоуровневые, и низкоуровневые попытки проектирования следует повторять. Первая попытка мо- жет привести к работоспособному решению, но едва ли оно окажется наилучшим.
Неоднократное применение разных подходов позволяет узнать о проблеме много такого, что ускользает при использовании единственного подхода.
Идея итерации снова вступает в игру при оптимизации кода. Как только ПО до- ведено до работоспособного состояния, вы можете переписать небольшие фраг- менты кода и добиться значительного повышения общей производительности системы. Однако многие попытки оптимизации ухудшают, а не улучшают код. Это неинтуитивный процесс, и некоторые методики, которые будто должны сделать систему более компактной и быстрой, на самом деле увеличивают ее и замедля- ют. Неопределенность результатов любого вида оптимизации заставляет пробо- вать один вид, оценивать быстродействие и пробовать другой. Если от устране- ния узкого места зависит достижение нужной производительности, вы можете оптимизировать код несколько раз, и более поздние попытки могут оказаться успешнее первой.
Весь процесс разработки охвачен обзорами, что встраивает итерацию в любой этап, на котором они проводятся. Цель обзора — проверка качества работы, вы- полненной на данный момент. Если система не проходит обзора, она возвраща- ется на переработку. Если обзор проходит успешно, дальнейшая итерация не нужна.
Говорят, инженерное дело — это умение сделать за 10 центов то, что любой мо- жет сделать за доллар. Итерация на более поздних этапах — это трата двух долла- ров на то, что любой может сделать за один. Фред Брукс советует «планировать выбросить один вариант программы, потому что это придется сделать в любом случае» (Brooks, 1995). Хитрость разработки ПО в том, чтобы создавать выбрасы- ваемые части как можно быстрее и дешевле — это и есть суть итерации на ран- них этапах разработки.

ГЛАВА 34 Основы мастерства
831
34.9. И да отделена будет религия
от разработки ПО
Религия проявляется в разработке ПО по-разному: как догматичное следование единственной методике проектирования, как непоколебимая убежденность в пре- восходстве отдельного стиля форматирования или комментирования или как рьяный отказ от глобальных данных. Как бы то ни было, это всегда неуместно.
Оракулы программирования
Увы, догматиками бывают и некоторые из наиболее уважа- емых людей в нашей отрасли. Конечно, инновационные методики нужно разглашать, чтобы их могли попробовать практикующие разработчики. До того как эффективность методик можно будет полностью доказать или опровергнуть,
их нужно испытать. Распространение результатов исследо- ваний на практикующих специалистов называется «передачей технологий» и иг- рает важную роль в совершенствовании способов разработки ПО. Однако распро- странение новой методологии нужно отличать от продажи чудодейственного средства от всех болезней программирования. Передача технологий — это совсем не то, чем занимаются торговцы догматичными методологиями, пытающиеся убедить вас в том, что их высокотехнологичная новинка решит все проблемы всех программистов во Вселенной. Забудьте обо всем, что вы изучили, потому что эта великолепная новая методика повысит производительность вашего труда в два раза во всех областях!
Вместо чрезмерного увлечения модными штучками используйте смесь методик.
Экспериментируйте с интересными новыми методиками, но делайте ставку на старые и надежные.
Эклектизм
Слепая вера в одну методику подавляет возможность выбо- ра, нужную для обнаружения наиболее эффективных реше- ний проблем. Будь разработка ПО детерминированным ал- горитмическим процессом, вы могли бы следовать жесткой методологии. Однако разработка ПО — не детерминирован- ный, а эвристический процесс, а значит, жесткие подходы редко приводят к успеху. Например, при проектировании иногда хорошо работает нисходящая декомпозиция, но иногда лучшим вариантом будет объектно-ориентированный подход, восходящая композиция или подход, основанный на структурах данных. Вы должны быть готовы к испытанию нескольких подходов, зная, что некоторые окажутся неэф- фективными, а какие-то приведут к успеху, но не зная заранее, какие из них ка- кие. Вам следует быть эклектичным.
Приверженность одной методике вредна и тем, что она заставляет подгонять проблему под решение. Выбирая методику решения до полного понимания про- блемы, вы слишком спешите. Чрезмерное ограничение набора возможных реше- ний может исключить из области видимости наиболее эффективное решение.
Перекрестная ссылка О том, как руководителям следует подхо- дить к религии программирова- ния, см. подраздел «Вопросы религии» раздела 28.5.
Перекрестная ссылка О разли- чии между алгоритмическим и эвристическим подходами см.
раздел 2.2, об эклектизме при проектировании — подраздел
«Используйте итерацию» разде- ла 5.4.

832
ЧАСТЬ VII Мастерство программирования
Любая новая методология поначалу вызывает дискомфорт, и совет избегать ре- лигии в программировании не подразумевает, что от новой методики следует отказаться при возникновении небольшой проблемы. Пересмотрите новую мето- дику, но не забывайте пересматривать и старые методики.
С позиций эклектизма полезно подходить и к методикам,
описанным в этой книге, и к методикам, рассматриваемым в других источниках. Некоторые подходы, представленные мной, имеют улучшенные альтернативы, и вы не можете ис- пользовать их одновременно. Вы должны выбрать для конк- ретной проблемы один или другой подход. Рассматривайте методики как инструменты и выбирайте наиболее подходящую для работы. В боль- шинстве случаев выбор инструмента не играет особой роли. Вы можете использо- вать торцовый ключ, плоскогубцы или разводной ключ. Однако иногда выбор очень важен, поэтому вам следует всегда делать выбор со всей тщательностью. Разработ- ка предполагает нахождение компромисса между конкурирующими методиками. Вы не сможете достичь компромисса, если преждевременно ограничите выбор един- ственным инструментом.
Метафора инструментария полезна потому, что она делает абстрактную идею эклектизма конкретной. Если бы вы строили дом и ваш приятель Симпл Саймон всегда работал только плоскогубцами, отказываясь от торцового или разводного ключей, вы, вероятно, подумали бы, что он ведет себя странно, потому что не использует все инструменты, имеющиеся в его распоряжении. То же верно и при разработке ПО. На высоком уровне у вас есть альтернативные методики проекти- рования. На более детальном уровне вы можете выбрать для представления кон- кретной сущности один из нескольких типов данных. На еще более детальном уровне вы можете выбирать схемы форматирования и комментирования кода,
именования переменных, определения интерфейсов классов и передачи парамет- ров в методы.
Догматизм конфликтует с эклектичным подбором инструментов к конструиро- ванию ПО. Она несовместима с психологической установкой, необходимой для создания высококачественных программ.
Экспериментирование
Эклектизм тесно связан с экспериментированием. Вам нужно экспериментиро- вать на всем протяжении процесса разработки, но непреклонность подавляет этот импульс. Чтобы экспериментирование было эффективным, вы должны охотно изменять свои убеждения на основе результатов экспериментов — иначе экспе- риментирование становится пустой тратой времени.
Многие негибкие подходы к разработке ПО основаны на страхе допустить ошибку,
но нет ошибки серьезнее, чем глобальное стремление избежать ошибок. Проек- тирование — это процесс тщательного планирования мелких ошибок с целью предотвращения крупных. Экспериментирование при разработке ПО позволяет узнать, эффективен ли тот или иной подход, — сам эксперимент является успе- хом, если он решает проблему.
Перекрестная ссылка О метафо- ре инструментария см. подраз- дел «Применение методов раз- работки ПО: интеллектуальный инструментарий» раздела 2.3.

ГЛАВА 34 Основы мастерства
833
Экспериментирование уместно на стольких же уровнях, что и эклектизм. На каж- дом уровне, предоставляющем возможность эклектичного выбора, вы, вероятно,
можете провести соответствующий эксперимент для определения оптимального подхода. На уровне разработки архитектуры эксперимент может заключаться в проектировании архитектуры ПО с использованием трех разных подходов.
На уровне детального проектирования эксперимент может состоять в детализа- ции высокоуровневой архитектуры с использованием трех разных подходов к низ- коуровневому проектированию. На уровне языка программирования эксперимен- том может быть написание небольшой экспериментальной программы для изу- чения плохо знакомых вам аспектов языка. Эксперимент может заключаться в оптимизации фрагмента кода и оценке того, действительно ли он стал меньше или быстрее. На уровне общего процесса разработки ПО эксперимент может за- ключаться в сборе данных о качестве и производительности труда, отвечающих на вопрос, действительно ли инспекции позволяют обнаружить больше ошибок,
чем анализ кода.
Суть сказанного в том, что вы должны быть восприимчивы ко всем аспектам раз- работки ПО. Вы должны разобраться и в используемом процессе разработки, и в создаваемой системе. Непредвзятое экспериментирование и религиозное следо- вание предопределенному подходу исключают друг друга.
Ключевые моменты

Главная цель программирования — управление сложностью.

Процесс программирования оказывает большое влияние на итоговый продукт.

Групповое программирование является в большей степени общением с други- ми людьми, а не с компьютером. Индивидуальное программирование — это в первую очередь общение с самим собой, а не с компьютером.

При неадекватном использовании конвенция программирования может ока- заться лекарством, причиняющим больше вреда, чем болезнь; при грамотном
— конвенция добавляет ценную структуру в среду разработки, помогает управ- лять сложностью и облегчает общение.

Программирование в терминах проблемы, а не решения помогает управлять сложностью.

Внимание к интеллектуальным предупреждающим знакам вроде сомнения особенно важно в программировании, потому что программирование — по- чти исключительно умственная деятельность.

Чем больше внимания итерации вы уделяете на конкретном этапе разработ- ки, тем лучше будет результат этого этапа.

Догматичные методологии и разработка высококачественного ПО исключают друг друга. Заполняйте свой интеллектуальный инструментарий альтернатив- ными подходами к программированию и улучшайте навык выбора инструмента,
лучше всего подходящего для работы.
Источник: https://files.student-it.ru/previewfile/206183