Файл: Руководство по стилю программирования и конструированию по.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 797
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
1 ... 93 94 95 96 97 98 99 100 ... 104
ГЛАВА 34 Основы мастерства
821
Низкоуровневые процессы тоже важны. Если вы пишете псевдокод, после чего создаете соответствующий ему реаль- ный код, вы используете все преимущества нисходящего проектирования. Кроме того, так вы всегда будете иметь комментарии в коде, и потом вам не придется их писать.
Чтобы проанализировать общие и частные процессы, нужно сделать паузу и об- ратить внимание на то, как вы создаете ПО. Это время тратится с пользой. Про- граммисты, руководствующиеся принципом «код — вот, что важно; сосредоточи- ваться надо на качестве кода, а не какого-то абстрактного процесса», поступают недальновидно, игнорируя горы экспериментальных и практических данных,
свидетельствующих об обратном. Разработка ПО — процесс творческий. Если вы не понимаете сути этого процесса, ваш главный инструмент — мозг — часто ра- ботает вхолостую. Плохо организованный процесс заставляет тратить умствен- ные ресурсы впустую, хорошо — позволяет извлечь из них максимальную выгоду.
34.3. Пишите программы в первую очередь
для людей и лишь во вторую —
для компьютеров
Ваша программа. Лабиринт нелогичных заключений, замусоренный замыс-
ловатыми хитростями и нерелевантными комментариями. Сравните с МОЕЙ
ПРОГРАММОЙ.
Моя программа. Бриллиант детерминированной точности, воплотивший
в себе совершенное равновесие между компактностью и эффективностью кода,
с одной стороны, и превосходной удобочитаемостью, дополненной полным
набором комментариев, — с другой. Сравните с ВАШЕЙ ПРОГРАММОЙ.
Стэн Келли-Бутл (Stan Kelly-Bootle)
Еще один лейтмотив данной книги — удобочитаемость кода. Общение с другими людьми — вот Святой Грааль самодокументирующегося кода.
Компьютерам все равно, насколько удобочитаем ваш код. Они вообще лучше чи- тают двоичные команды, а не операторы высокоуровневых языков. Удобочитае- мый код нужно писать для того, чтобы он был понятен людям. Читабельность положительно влияет на такие аспекты программы, как:
쐽
понятность;
쐽
легкость выполнения обзоров;
쐽
уровень ошибок;
쐽
удобство отладки;
쐽
легкость изменения;
쐽
время разработки — следствие всего вышеперечисленного;
쐽
внешнее качество — следствие всего вышеперечисленного.
Перекрестная ссылка Об итера- ции см. раздел 34.8.
822
ЧАСТЬ VII Мастерство программирования
Удобочитаемый код писать ничуть не дольше, чем запутан- ный — по крайней мере в далекой перспективе. В работо- способности кода легче убедиться, если вы можете с легко- стью прочесть то, что написали, и уже одного этого доста- точно для работы над понятностью кода. Однако код чита- ют и во время обзоров. И при исправлении ошибок. И при изменениях программы. Наконец, его читают, когда кто-то другой пытается использовать фрагмент вашего кода в по- хожей программе.
Работу над читабельностью кода не следует считать необя- зательной частью процесса разработки, и достижение удоб- ства во время написания за счет удобства во время чтения едва ли можно признать удачным решением. Лучше один раз написать хороший код, чем раз за разом читать плохой.
«Что, если я просто пишу код для себя? Почему я должен делать его удобочитаемым?» Потому что через неделю-две вы будете работать над другой программой и подумаете: «Эй!
Я уже написал этот класс на прошлой неделе. Я просто возьму мой старый протестированный отлаженный код и сэконом- лю время». Если код неудобочитаем, желаю удачи — она вам пригодится.
Оправдывать написание нечитаемого кода тем, что над проектом работаете только вы, опасно. Помните, как ваша мать говорила: «Что, если твое лицо застынет в этом выражении?», а отец — «Ты играешь так, как тренируешься». Привычки влияют на всю вашу работу, и вы не можете изменить их, просто захотев этого, поэтому убе- дитесь, что используемые вами подходы, став привычками, вас устроят. Профес- сиональные программисты пишут удобочитаемый код, и точка.
Поймите также, что утверждение, согласно которому код может принадлежать одному программисту, спорно. В связи с этим Дуглас Комер провел полезное раз- личие между личными и общими программами (Comer, 1981): «личные програм- мы» используются только программистом. Никто другой их не использует. Никто другой их не изменяет. Никто даже не знает об их существовании. Такие программы обычно тривиальны и крайне редки. А вот «общие программы» используются или изменяются не только автором, но и кем-то еще.
Стандарты, которым должны соответствовать общие и личные программы, могут различаться. Личные программы могут быть плохо написаны и полны ограниче- ний, и это не затронет никого, кроме автора. Общие программы нужно писать более внимательно: их ограничения следует документировать, а сами программы сле- дует делать надежными и модифицируемыми. Опасайтесь превращения личных программ в общие, что происходит довольно часто. Преобразовать личную про- грамму в общую нужно до того, как она поступит в обращение, и один из аспек- тов этого преобразования — улучшение читабельности кода.
Даже если вы думаете, что код будете читать только вы, в реальном мире высока вероятность того, что его придется изменять кому-то другому. Одно из исследований показало, что среднюю программу сопровождали 10 по- колений программистов, пока она не была переписана (Thomas, 1984). Програм-
На заре программирования про- грамма считалась частной соб- ственностью программиста. Чте- ние чужой программы без спроса было не меньшей наглостью, чем чтение любовного письма. По сути этим и являлась програм- ма — любовным письмом про- граммиста компьютеру, полным интимных деталей, известных только партнерам. Программы заполнялись кличками домаш- них животных и сокращениями,
столь популярными у влюблен- ных, живущих в благословенной абстракции и не замечающих больше никого во Вселенной.
Всем остальным людям такие программы непонятны.
Майкл Маркотти
(Michael Marcotty)
ГЛАВА 34 Основы мастерства
823
мисты, отвечающие за сопровождение, тратят от 50 до 60% времени, пытаясь по- нять код, и они по достоинству оценят ваши усилия, потраченные на его доку- ментирование (Parikh and Zvegintzov, 1983).
В предыдущих главах были рассмотрены методики улучшения удобочитаемости кода: грамотный выбор имен классов, методов и переменных, тщательное фор- матирование, сокращение объема методов, сокрытие сложных логических тестов в булевых функциях, присваивание промежуточных результатов сложных вычис- лений переменным и т. д. Никакая одна методика не сделает запутанную программу читабельной, однако сумма многих небольших улучшений будет существенной.
Если вы считаете, что какой-то код не нужно делать удобочитаемым, потому что никто другой никогда не будет иметь с ним дело, проверьте, не путаете ли вы причину и следствие.
34.4. Программируйте с использованием языка,
а не на языке
Не ограничивайте свое мышление только теми концепциями, которые непосред- ственно поддерживаются языком. Самые лучшие программисты думают о том, что они хотят сделать, после чего определяют, как достичь этих целей при помощи инструментов программирования, имеющихся в их распоряжении.
Разумно ли создавать метод-член класса, не согласующийся с абстракцией клас- са, только потому, что он удобнее метода, обеспечивающего более высокую со- гласованность? Код должен как можно надежнее защищать абстракцию, форми- руемую интерфейсом класса. Не нужно использовать глобальные данные или операторы
goto только потому, что их поддерживает язык. Вы можете отказаться от опасных возможностей и применять вместо них соглашения программирова- ния, компенсирующие слабости языка. Выбирать самые очевидные пути — зна- чит программировать
на языке, а не с использованием языка; в программирова- нии этот выбор эквивалентен вопросу: «Если Фредди спрыгнет с моста, прыгнете ли вы за ним?» Подумайте о своих целях и решите, как лучше всего достичь их,
программируя
с использованием языка.
Ваш язык не поддерживает утверждения? Напишите собственный метод
assert(). Пусть он работает не совсем так, как встроенный
assert(), но вы все же сможете задей- ствовать большинство преимуществ этого подхода. Ваш язык не поддерживает пе- речисления или именованные константы? Прекрасно: определите собственные перечисления и именованные константы путем дисциплинированного использо- вания глобальных переменных, дополненного ясными конвенциями именования.
В крайних случаях — особенно в новых технологических средах — инструменты бывают такими примитивными, что разработчикам приходится значительно из- менять свой желательный подход к программированию. Иногда это заставляет уравновешивать желание программировать с использованием языка и несуществен- ные сложности, возникающие из-за того, что особенности языка делают ваш подход слишком неуклюжим. Однако, попав в такие условия, вы сможете извлечь даже большую выгоду из соглашений программирования, помогающих избавиться от наиболее опасных возможностей среды. Как бы то ни было, обычно несоответ-
824
ЧАСТЬ VII Мастерство программирования ствие между тем, что вы хотите сделать, и тем, что уже поддерживают инструмен- ты, невелико и заставляет идти лишь на небольшие уступки.
34.5. Концентрируйте внимание
с помощью соглашений
Набор соглашений — один из интеллектуальных инструмен- тов управления сложностью. В предыдущих главах мы го- ворили о специфических конвенциях. В этом разделе я по- ясню на примерах общие преимущества соглашений.
Многие аспекты программирования в чем-то произвольны.
Какой длины отступ делать перед циклом? Как форматиро- вать комментарии? Как упорядочивать методы класса? Боль- шинство подобных вопросов не имеет одного правильного ответа. Конкретный ответ на такой вопрос менее важен, чем его согласованность. Соглашения избав- ляют программистов от необходимости снова и снова отвечать на те же вопросы и принимать все те же произвольные решения. В проектах, реализуемых многи- ми программистами, соглашения предотвращают замешательство, возникающее,
когда разные программисты принимают разные решения.
Конвенция лаконично сообщает важную информацию. В случае соглашений име- нования один символ может обеспечить различие между локальными перемен- ными, глобальными и переменными класса, регистр букв может указать на типы,
именованные константы и переменные. Соглашения использования отступов могут охарактеризовать логическую структуру программы. Соглашения выравнивания указывают на связь операторов.
Соглашения защищают от известных опасностей. Вы можете задать соглашения для исключения применения опасных методик, для ограничения их использова- ния в ситуациях, когда эти методики действительно нужны, или для компенсации их известных недостатков. Так, вы можете исключить опасность, запретив при- менение глобальных переменных или объединение нескольких команд в одной строке. Вы можете компенсировать слабости опасных методик, потребовав за- ключать сложные выражения в скобки или устанавливать указатели в
NULL сразу после их освобождения для предотвращения «зависания» указателей.
Соглашения делают более предсказуемыми низкоуровневые задачи. Наличие со- глашений обработки запросов памяти и обработки ошибок или соглашений вво- да/вывода и создания интерфейсов классов добавляет в код выразительную струк- туру и делает его понятнее программистам, знающим об этих соглашениях. Как я уже говорил, одно из главных преимуществ устранения глобальных данных со- стоит в исключении потенциальных взаимодействий между разными классами и подсистемами. Программист, читающий код, примерно представляет, чего мож- но ожидать от локальных данных и данных класса, но едва ли он может опреде- лить, что изменение глобальных данных портит какой-то бит в коде подсистемы,
находящейся на обратной стороне программы. Глобальные данные вносят в код неопределенность. Хорошие соглашения позволяют вам и людям, читающим ваш код, больше принимать как данное. Число деталей, которые нужно охватить, умень- шается, а это в свою очередь облегчает понимание программы.
Перекрестная ссылка О полез- ности соглашений в контексте форматирования кода см. под- разделы «Насколько важно хо- рошее форматирование?» и
«Цели хорошего форматирова- ния» раздела 31.1.