Главная - Литература

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 [274] 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

(McConnell, 2004). Чем бы программирование ни было - искусством, ремеслом или инженерной дисциплиной, создание работающей программы требует изрядной доли рассудительности. А для этого нужно обращать внимание на широкий диапазон предупреждающих знаков - тонких намеков на проблемы в вашей программе. Предупреждающие знаки в программировании указывают на возможные проблемы, но обычно они не настолько очевидны, как дорожный знак, предупреждающий о камнепадах.

Слова «Это по-настоящему хитрый код» обычно предупреждают о том, что код плох. «Хитрый» код - это другое название «плохого» кода. Если код кажется вам хитроумным, подумайте, не переписать ли его, чтобы он таким не был.

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

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

Как аномальное число дефектов в классе предупреждает о низком качестве класса, так и аномальное число дефектов в программе свидетельствует о неэффективности процесса разработки. Хороший процесс не привел бы к получению дефектного кода. Он включил бы проверку архитектуры, за которой последовали бы обзоры архитектуры, проектирование с обзорами проекта и кодирование с обзорами кода. Ко времени тестирования кода большинство ошибок было бы устранено. Для достижения высочайшей производительности труда нужно работать не просто усердно, но и разумно. Большой объем отладки предупреждает о том, что программисты не работают разумно. Написать большой фрагмент кода за день и потратить две недели на его отладку - это и есть неразумная работа.

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

Любой предупреждающий знак должен заставить вас сомневаться в качестве программы. Как говорит Чарльз Саундерс Пирс (Charles Saunders Peirce), «сомнение - это неловкое и неприятное состояние, от которого мы стараемся освободиться, перейдя в состояние убежденности». Рассматривайте предупреждающие знаки как «причины сомнения», побуждающие искать более приятное состояние убежденности.



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

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

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

Если вы хотите воспользоваться всеми преимуществами предупреждающих знаков, программируйте так, чтобы создать собственные предупреждения. Это полезно потому, что, даже если вам известны предупреждающие знаки, их на удивление легко упустить из виду Гленфорд Майерс исследовал исправления дефектов и обнаружил, что самой частой причиной плохого обнаружения ошибок была простая невнимательность. Ошибки были видны в результатах тестов, но программисты их не замечали (Myers, 1978b).

Программируйте так, чтобы ошибки было трудно не заметить. Примером этого может служить установка указателей в NULL после их освобождения, чтобы их ошибочное использование вызывало безобразные проблемы. Освобожденный указатель даже после освобождения может указывать на корректную область памяти. Установка указателя в NULL гарантирует, что он будет указывать на некорректный адрес, благодаря чему ошибку будет сложнее не заметить.

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

Почему внимание к интеллектуальным предупреждающим знакам особенно важно при разработке ПО? Качество мышления, воплощаемое в программе, во многом определяет качество самой программы, поэтому внимание к предупреждениям о качестве мышления напрямую влияет на итоговый продукт.



34.8. Итерируйте, итерируйте и итерируйте

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

Оценки сроков при первоначальном планировании проекта могут сильно различаться в зависимости от используемой методики оценки (см. главу 28). Итеративный подход дает более точную оценку, чем единственная методика.

Проектирование ПО - процесс эвристический и, как все эвристические процессы, допускает итеративные ревизии и улучшения. Правильность ПО обычно проверяется, а не доказывается, а значит, оно тестируется и разрабатывается итеративно, пока на все вопросы не будут получены правильные ответы. И высокоуровневые, и низкоуровневые попытки проектирования следует повторять. Первая попытка может привести к работоспособному решению, но едва ли оно окажется наилучшим. Неоднократное применение разных подходов позволяет узнать о проблеме много такого, что ускользает при использовании единственного подхода.

Идея итерации снова вступает в игру при оптимизации кода. Как только ПО доведено до работоспособного состояния, вы можете переписать небольшие фрагменты кода и добиться значительного повышения общей производительности системы. Однако многие попытки оптимизации ухудшают, а не улучшают код. Это неинтуитивный процесс, и некоторые методики, которые будто должны сделать систему более компактной и быстрой, на самом деле увеличивают ее и замедляют. Неопределенность результатов любого вида оптимизации заставляет пробовать один вид, оценивать быстродействие и пробовать другой. Если от устранения узкого места зависит достижение нужной производительности, вы можете оптимизировать код несколько раз, и более поздние попытки могут оказаться успешнее первой.

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

Говорят, инженерное дело - это умение сделать за 10 центов то, что любой может сделать за доллар. Итерация на более поздних этапах - это трата двух долларов на то, что любой может сделать за один. Фред Брукс советует «планировать выбросить один вариант программы, потому что это придется сделать в любом случае» (Brooks, 1995). Хитрость разработки ПО в том, чтобы создавать выбрасываемые части как можно быстрее и дешевле - это и есть суть итерации на ранних этапах разработки.



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 [274] 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294



0.015