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

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

Используйте наступательное программирование

Исключительные случаи должны обрабатываться так, что- -

Пштйпт еттш (М обра-

бы во время разработки они были очевидны, а в промыш- нтрщттш fmm

ленном коде - позволяли продолжить работу. Майкл Ховард поа)аадея «Оо»еш «о

и Дэвид Леблан назвали этот подход «наступательным про- пользованию оператороа т$$

граммированием» (Howard and LeBlanc, 2003). раздела 16»2,

Допустим, у вас есть оператор case, который, как вы ожидаете, будет обрабатывать только 5 видов событий. Во время разработки вариант по умолчанию нужно использовать для генерации предупреждения «Эй! Здесь еще один вариант! Исправьте программу!». Однако в промышленной версии реакция в этом случае должна быть более вежливой. Можно, например, делать запись в журнал ошибок.

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

Убедитесь, что утверждения завершают работу програм- о приносит меньше ереда, нш мы. Нельзя, чтобы у программистов вошло в привычку работающая плохо, просто нажимать клавишу Enter для пропуска уже изве- Эиди Хаит и Дэйв Томшо стной проблемы. Сделайте проблему достаточно мучи- [Шу Hunt Ш От Штв$) тельной, чтобы ее исправили.

Заполняйте любую выделенную память, чтобы можно было обнаружить ошибки выделения памяти.

Заполняйте все файлы и потоки, чтобы выявить ошибки файловых форматов.

Убедитесь, что при попадании в ветвь default или else всех операторов case программа прекращает работу или еще как-то заставляет обратить на это внимание.

Заполняйте объекты мусором перед самым их удалением.

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

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

Запланируйте удаление отладочных средств

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

Для контроля версий и сборки программы используй- щлшг О конт о те инструменты ant и make Средства контроля версий радея 22" позволяют создавать варианты программы из одних и тех

же исходных файлов. А инструменты для сборки позволяют вам настроить включение отладочного кода в режиме разработки и его исключение в коммерческой версии.



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

Пример непосредственного использования препроцессора для управления отладочным кодом (С++)

- Для добавления кода отладки используйте директиву define, чтобы определить символ DEBUG. Для исключения отладочного кода просто не определяйте DEBUG.

->#define DEBUG

#if defined( DEBUG ) отладочный код

#endif

У этой темы несколько вариаций. Вместо простого определения DEBUG вы можете присвоить ему значение, а затем проверять именно это значение, а не просто факт определения символа. Так вы можете различать несколько уровней отладочного кода. Какой-то код вы хотели бы использовать в программе все время, поэтому вы окружаете его операторами вроде DEBUG > 0. Другой отладочный код может понадобиться только в специальных целях, и вы можете заключить его в операторы if DEBUG == POINTERERROR. В других местах вы захотите установить различные уровни отладки, для чего годятся такие выражения, как DEBUG > LEVEL A.

Если вы не хотите распространять definedQ по всему коду, можно написать макрос препроцессора, выполняющий ту же задачу. Вот его пример:

Пример использования макроса препроцессора для управления отладочным кодом на С++

#define DEBUG

#if defined( DEBUG )

define DebugCode( code fragment ) { code fragment } else

#define DebugCode( code fragment ) #endif

DebugCode(

• Этот код добавляется или удаляется в зависимости от того, определен ли символ DEBUG.

statement 1; statement 2;

statement n;



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

Напишите собственный препроцессор Если язык не п«„«««,„,„ л «..„

перехрастная ссылка и препро-

содержит препроцессор, то для включения/исключения от- цессорах и источниках йнфор-ладочного кода довольно легко написать свой. Разработай- мации об ш нашсании см, под-те правила для добавления отладочного кода и напишите раздел «Препроцессоры» разде-свой прекомпилятор, следующий этим соглашениям. Скажем, в Java вы могли бы написать прекомпилятор для обработки ключевых слов BEGIN DEBUG и *END DEBUG. Напишите сценарий для вызова препроцессора, а затем скомпилируйте полученный после него код. В долгосрочной перспективе вы сбережете время. Кроме того, вы не сможете случайно скомпилировать необработанный код.

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

Вы можете начать с метода, разработанного для проверки переданных ему указателей:

Пример метода, использующего отладочную заглушку (С++)

void DoSomething(

SOME TYPE -pointer;

проверка переданных сюда параметров - Это строка вызывает процедуру для проверки указателя.

-> CheckPointer( pointer );

Во время разработки процедура CheckPointerQ будет выполнять полную проверку указателя. Это будет медленно, но эффективно, например, так:



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.0033