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

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

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

Комментарии по поводу минимизации области видимости

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

Другие предпочитают делать переменные как можно более Певекреш»! ««ый1со Идея мй*

нймйзацйи области &ттош -вокальными, потому что локальная область видимости спо-свшт с идеей сокрытия т- собствует интеллектуальной управляемости. Чем больше формаций [см, подраздел информации вы скрыли, тем меньше вам нужно удерживать «Скрывайте секреты (к вопро* в уме в каждый конкретный момент времени и тем ниже су о сокрытйи информации)» вероятность того, что вы допустите ошибку, забыв одну из раздела 5.3.

многих деталей, о которых нужно было помнить.

Разница между философией «удобства» и философией «интеллектуальной управляемости» сводится к различию между ориентацией на написание программы и ориентацией на ее чтение. Максимизация области видимости может облегчить написание программы, но программу, в которой каждый метод может вызвать любую переменную в любой момент времени, сложнее понять, чем код, основанный на грамотно организованных методах. Сделав данные глобальными, вы не сможете ограничиться пониманием работы одного метода: вы должны будете понимать работу всех других методов, которые вместе с ним используют те же глобальные данные. Подобные программы сложно читать, сложно отлаживать и сложно изменять.

Пврекреошя шша О методах ™ ограничивайте область видимости каждой перемен-доступа см. подаздел «Йсполь- минимальным фрагментом кода. Можете ограничить ее

зова«ие методов доступа ть- одним циклом или одним методом - великолепно! Не посте глобальных данных»» раде- лучается - ограничьте область видимости методами одно-

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



10.5. Персистентность

«Персистентность» - это еще одно слово, характеризующее длительность существования данных. Персистентность принимает несколько форм. Некоторые переменные «живут»:

пока выполняется конкретный блок кода или метод: например, это переменные, объявленные внутри цикла for языка С++ или Java;

столько, сколько вы им позволяете: в Java переменные, созданные при помощи оператора new, «живут» до сборки мусора; в С++ созданные аналогично переменные существуют, пока не будут уничтожены с помощью оператора delete-,

до завершения программы: этому описанию соответствуют глобальные переменные в большинстве языков, а также статические переменные в языках С++ и Java;

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

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

Проблем подобного рода можно избежать.

Включайте в программу отладочный код или утвержде-

ния для проверки важных переменных на предмет до-

пустимости их значений. Если значения недопустимы, доступа (см. пойраздел

отображайте предупреждение, рекомендующее присту- «Преимущества методов досту-пить к поиску кода неверной инициализации. з» раздела 13.3).

Завершив работу с переменными, присваивайте им «недопустимые значения». Скажем, после освобождения памяти при помощи оператора delete вы может установить указатель в null

Исходите из того, что данные не являются персистентными. Так, если при возврате из метода переменная имеет определенное значение, не предполагайте, что оно будет таким же при следующем вызове метода. Это правило неактуально, если вы используете специфические возможности языка, гарантирующие неизменность значения переменной, такие как ключевое слово static языков С++ и Java.

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



10.6. Время связывания

Одним из аспектов инициализации, серьезно влияющим на удобство сопровождения и изменения программы, является «время связывания» - момент, когда переменная и ее значение связываются вместе (Thimbleby, 1988). Связываются ли они при написании кода? При его компиляции? При загрузке? При выполнении программы? В другое время?

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

Пример связывания во время написания кода (Java)

titleBar.color = OxFF; OxFF - шестнадцатеричное значение синего цвета

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

В следующем примере связывание переменной выполняется чуть Позднее, во время компиляции кода:

Пример связывания во время компиляции (Java)

private static final int COLOR BLUE = OxFF;

private static final int TITLE BAR COLOR = COLOR BLUE;

titleBar.color = TITLE BAR COLOR;

В данном случае TITLE BARCOLOR является именованной константой - выражением, вместо которого компилятор подставляет конкретное значение при компиляции. Этот подход почти всегда лучше, чем жесткое кодирование. Он облегчает чтение кода, потому что имя константы TITLE BAR COLOR лучше характеризует представляемое ей значение, чем OxFF. Он облегчает изменение цвета заголовка окна (title bar), так как изменение константы будет автоматически отражено во всех местах, где она используется. При этом он не приводит к снижению быстродействия программы в период выполнения.

Вот пример еще более позднего связывания - в период выполнения:

Пример связывания в период выполнения (Java)

titleBar.color = ReaclTitleBarColor();

ReadTitleBarColorQ - это метод, который во время выполнения программы читает значение из реестра Microsoft Windows, файла свойств Java или подобного места.

Этот код более понятен и гибок, чем код с жестко закодированным значением. Чтобы изменить значение titleBar.color, вам не нужно изменять программу: достаточно просто изменить содержание файла, из которого метод ReadTitleBarColorQ



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