Источник: Стив Макконнелл "Совершенный код"
Исследования показали, что всем лучшим проектировщикам свойственно предвосхищать изменения (Glass, 1995). Обеспечение легкости адаптации программы к возможным изменениям относится к самым сложным аспектам проектирования. Его цель заключается в изоляции нестабильных областей, позволяющей ограничить следствия изменений одним методом, классом или пакетом. Вот как проходит подготовка к изменениям.
1. Определите элементы, изменение которых кажется вероятным.
Если вы выработали адекватные требования, они включают список потенциальных изменений и оценки вероятности каждого из них. В этом случае определить вероятные изменения легко. Если требования не описывают потенциальные изменения, ниже вы найдете список областей, которые меняются чаще всего независимо от типа проекта.
2. Отделите элементы, изменение которых кажется вероятным.
Создайте отдельный класс для каждого нестабильного компонента, определенного в п. 1, или разработайте классы, включающие несколько нестабильных компонентов, изменение которых скорее всего будет одновременным.
3. Изолируйте элементы, изменение которых кажется вероятным.
Спроектируйте интерфейсы между классами так, чтобы они не зависели от потенциальных изменений. Спроектируйте интерфейсы так, чтобы изменения ограничивались только внутренними частями классов. Изменение класса должно оставаться незаметным для любых других классов. Интерфейс класса должен защищать его секреты.
Ниже описано несколько областей, изменяющихся чаще всего.
Бизнес-правила Необходимость изменения ПО часто объясняется изменениями бизнес-правил. Оно и понятно: конгресс может изменить систему налогообложения, профсоюзы — пересмотреть условия контрактов и т. д. Если вы соблюдаете принцип сокрытия информации, логика, основанная на этих правилах, не будет распространена на всю программу. Она будет скрыта в одном темном уголке системы, пока не придет время ее изменить.
Зависимости от оборудования Примерами модулей, зависимых от оборудования, могут служить интерфейсы между программой и разными типами мониторов, принтеров, клавиатур, дисководов, звуковых плат и сетевых устройств. Изолируйте зависимости от оборудования в отдельной подсистеме или отдельном классе. Это облегчает адаптацию программы к новой аппаратной среде, а также помогает разрабатывать ПО для нестабильных версий устройств. Вы можете разработать ПО, моделирующее взаимодействие с конкретным устройством, и создать подсистему аппаратного интерфейса, использующую эту модель, пока устройство нестабильно или недоступно. Когда устройство будет готово к работе, подсистему интерфейса можно будет отключить от модели и подключить к устройству.
Ввод-вывод На чуть более высоком в сравнении с аппаратными интерфейсами уровне проектирования частой областью изменений является ввод-вывод. Если ваше приложение создает собственные файлы данных, его усложнение вполне может потребовать изменения формата файлов. Аспекты формата ввода-вывода данных, относящиеся к пользовательскому уровню, такие как позиционирование и число полей на странице, их последовательность и т. д., изменяются не менее часто. В общем, анализ всех внешних интерфейсов на предмет возможных изменений — благоразумная идея.
Нестандартные возможности языка Большинство версий языков поддерживает нестандартные расширения, облегчающие работу программистов. Расширения — палка о двух концах, потому что в другой среде — будь то другая аппаратная платформа, реализация языка другим производителем или новая версия языка, выпущенная тем же производителем, — они могут оказаться недоступны.
Если вы применяете нестандартные расширения языка, скройте работу с ними в отдельном классе, чтобы его можно было заменить при адаптации приложения к другой среде. Аналогично, используя библиотечные методы, доступные не во всех средах, скройте их за интерфейсом, поддерживающим все нужные среды.
Сложные аспекты проектирования и конструирования Скрывайте сложные аспекты проектирования и конструирования, потому что их частенько приходится реализовывать заново. Отделите их и минимизируйте влияние, которое может оказать их неудачное проектирование или конструирование на остальные части системы.
Переменные статуса Переменные статуса характеризуют состояние программы и изменяются чаще, чем большинство других видов данных. Так, разработчики, определившие переменную статуса ошибки как булеву переменную, вполне могут позднее прийти к выводу, что для этого лучше было бы использовать перечисление со значениями ErrorType_None, ErrorType_Warning и ErrorType_Fatal.
Использование переменных статуса можно сделать более гибким и понятным минимум двумя способами. В качестве переменных статуса примените не булевы переменные, а перечисления. Диапазон поддерживаемых переменными статуса состояний часто приходится расширять, что в случае перечисления требует лишь перекомпиляции программы, а не масштабной ревизии всех фрагментов кода, выполняющих проверку переменной.
Вместо непосредственной проверки переменной используйте методы доступа. Так вы сохраните возможность реализации более сложного механизма определения состояния. Например, если вы захотите проверять комбинацию переменной статуса ошибки и переменной текущего функционального состояния, вам будет легко реализовать это, если проверка будет скрыта в методе, и гораздо сложнее, если механизм проверки будет жестко закодирован во многих местах программы.
Размеры структур данных Объявляя массив из 100 элементов, вы раскрываете информацию, которую никто знать не должен. Защищайте право на личную жизнь! Сокрытие информации не всегда требует создания целого класса. Иногда для этого достаточно именованной константы: например , MAX_EMPLOYEES позволяет скрыть число 100.
Предвосхищение изменений разного масштаба Обдумывая потенциальные изменения системы, проектируйте ее так, чтобы влияние изменений было обратно пропорционально их вероятности. Если вероятность изменения высока, убедитесь, что систему будет легко адаптировать к нему. С большим влиянием на несколько классов системы можно смириться лишь в случае крайне маловероятных изменений. Грамотные проектировщики также принимают во внимание цену предвосхищения изменений. Если изменение маловероятно, но его легко предугадать, рассмотрите его внимательнее, чем более вероятное изменение, которое трудно спланировать.
Один хороший метод определения областей вероятных изменений подразумевает, что вы должны сначала определить минимальное подмножество фрагментов программы, необходимых пользователям. Это подмножество составляет ядро системы, и его изменения маловероятны. Затем вы определяете минимальные инкрементные приращения системы. Они могут быть совсем небольшими, даже тривиальными.
Вместе с функциональными изменениями рассматривайте также качественные изменения программы: обеспечение безопасности в многопоточной среде, поддержку механизмов локализации и т. д. Эти области потенциальных улучшений являются потенциальными изменениями системы; спроектируйте эти области, используя принципы сокрытия информации. Определив ядро в самом начале, вы поймете, какие компоненты системы на самом деле являются дополнениями, и сможете с этого момента экстраполировать и скрывать аспекты возможных изменений программы.
Скачать все книги в telegram
https://t.me/physics_lib
https://tlgg.ru/physics_lib
https://tgtg.su/physics_lib
https://telete.in/physics_lib
https://ttttt.me/physics_lib