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

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

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

Важность сокрытия информации

Сокрытие информации относится к тем немногим теоретическим подходам, польза которых уже долгое время неоспоримо подтверждается на практике (Boehm, 1987а). Было обнаружено, что крупные программы, использующие сокрытие информации, вчетверо легче модифицировать, чем программы, его не использующие (Korson and Vaishnavi, 1986). Более того, сокрытие информации - один из основных принципов и структурного, и объектно-ориентированного проектирования.

Сокрытие информации обладает уникальной эвристической силой, уникальной способностью подталкивать разработчиков к эффективным проектным решениям. Традиционное объектно-ориентированное проектирование предоставляет мощные эвристические средства моделирования мира в терминах объектов, но объектный подход не помог бы вам догадаться, что идентификатор следует объявить как IdType, а не как int. Разработчик, использующий объектно-ориентированный подход, спросил бы: «Рассматривать ли идентификатор как объект?» В зависимости от принятых в проекте стандартов кодирования утвердительный ответ мог бы означать, что программист должен написать конструктор, деструктор, операторы копирования и присваивания, закомментировать все это и сохранить в системе управления конфигурацией. Но скорее всего программист решил бы: «Нет, не стоит создавать целый класс ради какого-то идентификатора. Использую просто int».

Смотрите: эффективный вариант проектирования - простое сокрытие типа данных идентификатора - даже не был рассмотрен! Если бы вместо этого разработчик спросил: «Не скрыть ли информацию об идентификаторе?» - он, возможно, решил бы объявить собственный тип IdType как синоним int. Различие между объектно-ориентированным проектированием и сокрытием информации в этом примере не сводится к простому несоответствию явных правил и предписаний. Принятое в соответствии с принципом сокрытия информации решение прекрасно согласуется с объектно-ориентированным подходом. Вместо этого различие относится к области эвристики: размышление над сокрытием информации может указать на такие варианты проектирования, которые при использовании объектно-ориентированного подхода остались бы незамеченными.

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



что некоторые программисты скорее раскрыли бы все закрытые данные класса, чем написали 10 дополнительных строк для защиты его секретов.

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

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

Почаще задавайте себе вопрос «Что мне скрыть?», и вы удивитесь, сколько проблем проектирования растает на ваших глазах

Определите области вероятных изменений

Дшкшйитедьные сведши Под- Исследования показали, что всем лучшим проектировщикам ход. описанный в атом разде свойственно предвосхищать изменения (Glass, 1995). Обес-ле. взят из статьи «Ое$19п1п0 печение легкости адаптации программы к возможным изме-Software for Ease of Extension нениям относится к самым сложным аспектам проектирова-and Contraction* (Pamas, 1979). j заключается в изоляции нестабильных облас-

тей, позволяющей ограничить следствия изменений одним методом, классом или пакетом. Вот как проходит подготовка к изменениям.

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

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

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

Ниже описано несколько областей, изменяющихся чаще всего.

nteiqi№itaii еешка Один из Бизнес-правила Необходимость изменения ПО часто самых эффективных способов объясняется изменениями бизнес-правил. Оно и понятно: предвосхищения изменений - конгресс может изменить систему налогообложения, проф-тйичное управление (см, та- союзы - пересмотреть условия контрактов и т. д. Если вы

соблюдаете принцип сокрытия информации, логика, основанная на этих правилах, не будет распространена на всю



программу. Она будет скрыта в одном темном уголке системы, пока не придет время ее изменить.

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

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

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

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

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

Переменные статуса Переменные статуса характеризуют состояние программы и изменяются чаще, чем большинство других видов данных. Так, разработчики, определившие переменную статуса ошибки как булеву переменную, вполне могут позднее прийти к выводу, что для этого лучше было бы использовать перечисление со значениями ErrorTypeNone, ErrorTypeJWaming и ErrorType Fatah

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

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



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