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

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

Создание новой переменной workingVal поясняет роль inputVal и исключает возможность ошибочного использования inputVal в неподходящий момент. (Не рассматривайте это рассуждение как оправдание присвоения переменным имен inputVal или workingVal Имена inputVal и workingVal просто ужасны и служат в данном примере только для пояснения ролей переменных.)

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

Щщтш ш&т О связан- Документируйте выраженные в интерфейсе предпо-

ных о интерфейсами арерош- ложения о параметрах Если вы предполагаете, что пе-женш ш« также гшву 8, ь редаваемые в метод данные должны иметь определенные куманшрсшши кода-гшу 32. характеристики, сразу же документируйте эти предположения. Документирование предположений и в самом методе, и в местах его вызова нельзя назвать пустой тратой времени. Пишите комментарии, не дожидаясь завершения работы над методом: к тому времени вы многое забудете. Еще лучше применить утверждения (assertions), позволяющие встроить предположения в код.

Какие типы предположений о параметрах следует документировать? Вот какие:

вид параметров: являются ли они исключительно входными, изменяемыми или исключительно выходными;

единицы измерения (дюймы, футы, метры и т. д.);

смысл кодов статуса и ошибок, если для их представления не используются перечисления;

диапазоны допустимых значений;

специфические значения, которые никогда не должны передаваться в метод.

Ограничивайте число параметров метода примерно семью 7 -

магическое число. Психологические исследования показали, что люди, как правило, не могут следить более чем за семью элементами информации сразу (Miller, 1956). Это открытие используется в огромном числе дисциплин, поэтому резонно предположить, что большинство людей не может удерживать в уме более семи параметров метода одновременно.

Шрсшстош! шшт Ршт т- практике возможность ограничения числа параметров тврфейсов смх в п&дрщеяе «Xch зависит от того, как в выбранном вами языке реализована ршая абстракция* раздана bZ поддержка сложных типов данных. Программируя на современном языке, поддерживающем структурированные данные, вы можете передать в метод составной тип данных, содержащий 13 полей, и рассматривать его как один «элемент» данных. При использовании более примитивного языка вам, возможно, придется передать все 13 полей по отдельности.

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



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

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

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

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

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

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

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

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



Пример явной идентификации параметров (Visual Basic)

Private Function Distance3cl(

- Объявления формальных параметров.

ByVal xDistance As Coordinate, •- ByVal yDistance As Coordinate, ByVal zDistance As Coordinate )

End Function

Private Function Velocity(

ByVal latitude as Coordinate, ByVal longitude as Coordinate, ByVal elevation as Coordinate

- Сопоставление фактических параметров с формальными.

> Distance = Distance3d( xDistance := latitude, yDistance := longitude, zDistance := elevation )

End Function

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

Убедитесь, что фактические параметры соответствуют формальным Формальные параметры, известные также как «фиктивные параметры» (dummy parameters), - это переменные, объявленные в определении метода. Фактическими параметрами называют переменные, константы или выражения, на самом деле передаваемые в метод.

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



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