|
АРИС Текст 2. Водяхо А. И., Выговский Л. С., Дубенецкий В. А., Цехановский В. В. Архитектурные решения информационных систем
Контрольные вопросы 1. Как соотносятся понятия «архитектура и архитектурное описание?
2. Что такое архитектурное описание?
3. Что такое архитектурный процесс?
4. Что такое архитектурный фреймворк?
5. Определите понятие Архитектурный вид.
6. Определите понятие Архитектурная точка зрения.
7. Что такое интерес?
8. Определите понятие Заинтересованная сторона.
9. Для чего нужны языки описания архитектуры?
10. Чем отличаются UML и SysML?
11. В чем состоит основная идея архитектуры, управляемые моделями?
12. Что такое платформенно-независимая модель?
13. Что такое платформенно-зависимая модель?
14. Что такое метаметамодель?
15. Что такое архитектурные метрики?
ГЛАВА 8. ПАТТЕРНЫ И АНТИПАТТЕРНЫ
8.1. Понятие паттерна. Классификация паттернов
Паттерны (шаблоны) впервые появились в середине 90-х годов как составная часть объектно-ориентированного подхода и рассматривались как набор объектов, организованных определенным образом для решения конкретного класса задач. Следует заметить, что хотя применительно к ИС паттерны используются немногим более 20 лет, в других отраслях, в первую очередь в строительстве, они успешно используются уже много десятков лет. В качестве основополагающего исследования в области паттернов можно отметить [125], а в качестве наиболее полного – пятитомник, посвященный паттернам [25, 26, 27, 28, 29].
Обычно паттерн проектирования определяют как набор абстрактных классов, ориентированных на решение задач, относящихся к определенному домену. Паттерны проектирования иногда определяют как модель частичных решений, однако чаще их связывают с объектно-ориентированным программированием, хотя при работе с паттернами могут использоваться и другие парадигмы программирования. Следует заметить, что между объектами и паттернами нет жестких взаимных привязок и формирование концепции паттернов в рамках объектно-ориентированного подхода – это в определенной степени дело случая [125].
Полезность паттернов состоит и в том, что их использование позволяет выделить часто встречающиеся проблемы, дать им имена, предложить типовые решения, которые можно внедрять в создаваемые ИС. При использовании паттернов следует иметь в виду, что они не предоставляют готовый код. Функциональный код все равно приходится писать программисту.
Известны различные подходы к классификации паттернов. В [125] паттерны предлагается классифицировать с точки зрения уровня абстракции на концентуальные, паттерны проектирования и паттерны программирования
Концептуальные паттерны – это паттерны, функционирование которых описывается в терминах предметной области. Такие паттерны относятся к приложению в целом или крупным подсистемам ИС.
Паттерны проектирования – это паттерны, для описания которых используются термины, относящиеся к разработке программных систем, такие как объект, класс, модуль. Паттерны проектирования описывают решение общих проблем в конкретном контексте.
Программные паттерны – это паттерны, для описания которых используются такие относительно низкоуровневые понятия как деревья, списки и т.п.
Используется также классификация, в соответствии с которой выделяются следующие типы паттернов: архитектурные паттерны, системные паттерны, структурные паттерны, поведенческие паттерны, производящие паттерны [126]. Кроме того, паттерны можно разделить на паттерны общего назначения и доменно-ориентированные паттерны. Паттерны общего назначения не привязаны явным образом к той или иной предметной области (домену), а доменно-ориентированные паттерны имеют такую привязку. В дальнейшем будут рассматриваться только паттерны общего назначения.
Архитектурный паттерн (architectural patterns) описывает структуру программной системы и определяет состав подсистем, их основные функции и допустимые способы компоновки подсистем. Архитектурные паттерны называют также архитектурными стилями, которые были подробно рассмотрены ранее. Архитектурные паттерны являются описанием, которое не зависит ни от платформы, ни от языка программирования. Архитектурные паттерны можно рассматривать как паттерны высокого уровня.
8.2. Системные паттерны
Системные паттерны (system patterns) представляют приложение на верхнем (системном) уровне. Системные паттерны могут применяться в приложении для осуществления большинства процессов и даже для поддержки взаимодействия разных приложений. Системные паттерны можно рассматривать как паттерны, использование которых позволяет получить улучшенные архитектурные решения.
В табл. 8.1 представлены основные типы системных паттернов и их назначение.
Таблица 8.1
Основные типы системных паттернов
Типы системных паттернов
| Назначение
| Модель-Вид-Контроллер (Model-View-Controller (MVC))
| Разделение компонента или подсистемы на три логические части (модель, представление и контроллер) с целью облегчения модификации или настройки каждой части в отдельности
| Сессия (Session),
Рабочая нить (Worker Thread)
| Обеспечение серверам распределенных систем возможности различения клиентов, что позволяет приложениям ассоциировать определенные состояния с клиент/серверными коммуникациями
| Обратный вызов (Callback)
| Обеспечение клиенту возможности регистрации на сервере для выполнения расширенных операций. Это позволяет серверу извещать клиента о завершении операции
| Текущие обновления (Successive Update)
| Обеспечение клиенту возможности постоянного получения обновлений от сервера. Такие обновления обычно отражают изменения данных сервера, впервые появившиеся или обновленные ресурсы либо изменения в состоянии бизнес-модели
| Маршрутизатор (Router)
| Отделение источников информации от ее получателей
| Транзакция (Transaction)
| Группирование коллекций методов таким образом, чтобы они либо были все успешно выполнены, либо все завершились неудачно
| 8.3. Структурные паттерны
Структурные паттерны с одинаковой эффективностью применяются как для разделения, так и для объединения элементов приложения.
В табл. 8.2 представлены основные типы структурных паттернов и их назначение.
Способы воздействия структурных шаблонов на приложение могут быть самые разные. Например, шаблон Адаптер может обеспечить возможность двум несовместимым системам обмениваться информацией, тогда как шаблон Фасад позволяет отобразить упрощенный пользовательский интерфейс, не удаляя ненужных конкретному пользователю элементов управления.
Таблица 8.2
Основные типы структурных паттернов и их назначение
Типы структурных паттернов
| Назначение
| Адаптер (Adapter)
| Обеспечение взаимодействия двух классов путем преобразования интерфейса одного из них таким образом, чтобы им мог пользоваться другой класс.
| Мост (Bridge)
| Разделение сложного компонента на две независимые, но взаимосвязанные иерархические структуры: функциональную абстракцию и внутреннюю реализацию. Это облегчает изменение любого аспекта компонента.
| Композит (Composite)
| Предоставление гибкого механизма для создания иерархических древовидных структур произвольной сложности, элементы которых могут свободно взаимодействовать с единым интерфейсом.
| Декоратор (Decorator)
| Предоставление механизма для добавления или удаления функциональности компонентов без изменения их внешнего представления или функций.
| Фасад (Façade)
| Создание упрощенного интерфейса для группы подсистем или сложной подсистемы.
| Приспособленец (Flyweight)
| Уменьшение количества объектов системы с многочисленными низкоуровневыми особенностями путем совместного использования подобных объектов.
| Полуобъект и протокол (Half-Object Plus Protocol)
| Предоставление единой сущности, которая размещается в двух или более областях адресного пространства.
| Прокси (Proxy)
| Представление другого объекта, обусловленное необходимостью обеспечения доступа или повышения скорости либо соображениями безопасности.
| Поведенческие паттерны (behavioral patterns) применяются для передачи управления в системе. Существуют методы организации управления, применение которых позволяет добиться значительного повышения как эффективности системы, так и удобства ее эксплуатации. Поведенческие шаблоны представляют собой набор проверенных на практике методов и обеспечивают понятные и простые в применении эвристические способы организации управления.
В таблице 8.3 представлены основные типы поведенческих паттернов и их назначение.
Таблица 8.3
Основные типы поведенческих паттернов и их назначение
Типы поведенческих паттернов
| Назначение
| Цепочка ответственности (Chain of Responsibility)
| Для организации в системе уровней ,ответственности, позволяет установить, должно ли сообщение обрабатываться на том уровне, где оно было получено, или же оно должно передаваться для обработки другому объекту.
| Команда (Command)
| Обеспечивает обработку команды в виде объекта, что позволяет сохранять ее, передавать в качестве параметра методам, а также возвращать ее в виде результата, как и любой другой объект.
| Интерпретатор (Interpreter)
| Определяет интерпретатор некоторого языка.
| Итератор (Iterator)
| Предоставляет единый метод последовательного доступа к элементам коллекции, не зависящий от самой коллекции и никак с ней не связанный.
| Медиатор (Mediator)
| Упрощает взаимодействие объектов системы путем создания специального объекта, который управляет распределением сообщений между остальными объектами.
| Моментальный снимок (Memento)
| Сохраняет "моментальный список" состояния объекта, позволяющий такому объекту вернуться к исходному состоянию, не раскрывая своего содержимого внешнему миру.
| Состояние (State)
| Предоставляет компоненту возможность гибкой рассылки сообщений интересующим его получателям.
| Посетитель (Visitor)
| Обеспечивает простой и удобный в эксплуатации способ выполнения тех или иных операций для определенного семейства классов. Это достигается путем централизации с помощью данного шаблона возможных вариантов поведения, что позволяет модифицировать или расширять их, не затрагивая классы, на которые распространяются эти варианты поведения.
| Метод шаблона (Template Method)
| Предоставляет метод, который позволяет подклассам перекрывать части метода, не прибегая к их переписыванию.
| 8.4. Производящие паттерны
Производящие паттерны (creational patterns) предназначены для создания объектов в системе.
В ходе работы большинства объектно-ориентированных систем, независимо от уровня их сложности, создается множество экземпляров объектов. Производящие шаблоны облегчают процесс создания объектов, предоставляя разработчику следующие возможности:
единый способ получения экземпляров объектов, при этом в системе обеспечивается механизм создания объектов без необходимости идентификации определенных типов классов в программном коде; простота создания объектов до такой степени, что полностью избавляют разработчика от необходимости написания большого и сложного программного кода для получения экземпляра объекта; учет ограничений при создании объектов.
В табл. 8.4 представлены основные типы производящих паттернов и их назначение.
Таблица 8.4
Основные типы производящих паттернов и их назначение
Типы производящих паттернов
| Назначение
| Абстрактная фабрика (Abstract Factory)
| Обеспечивает создание семейств взаимосвязанных или зависящих друг от друга объектов без указания их конкретных классов.
| Строитель (Builder)
| Упрощает создание сложных объектов путем определения класса, предназначенного для построения экземпляров другого класса. Шаблон Builder генерирует только одну сущность. Хотя эта сущность в свою очередь может содержать более одного класса, но один из полученных классов всегда является главным.
| Метод фабрики (Factory Method)
| Определяет стандартный метод создания объекта, не связанный с вызовом конструктора, оставляя решение о том, какой именно объект создавать, за подклассами.
| Прототип (Prototype)
| Облегчает динамическое создание путем определения классов, объекты которых могут создавать собственные дубликаты.
| Одиночка (Singleton)
| Обеспечивает наличие в системе только одного экземпляра заданного класса, позволяя другим классам получать доступ к этому экземпляру.
| Два из перечисленных выше шаблона, а именно Abstract Factory и Factory Method, базируются исключительно на концепции определения создания настраиваемых объектов. Подразумевается, что разработчик, применяющий эти шаблоны, при модернизации системы обеспечит механизм расширения создаваемых классов или интерфейсов. В силу этой особенности данные шаблоны часто объединяются с другими производящими шаблонами.
8.5. Паттерны параллельного программирования
Паттерны параллельного программирования ориентированы на обеспечение корректного взаимодействия асинхронно протекающих процессов и ориентированы на решение двух основных задач: совместное использование ресурсов и управление доступом к ресурсам.
Совместное использование ресурсов. Если конкурирующие операции обращаются к одним и тем же данным или к общему ресурсу, то они могут конфликтовать друг с другом, если эти операции осуществляют доступ к ресурсу в один и тот же момент. Чтобы обеспечить корректное выполнение таких операций, их нужно ограничить таким образом, чтобы доступ к общему ресурсу в конкретный момент времени получала только одна операция, однако чрезмерное ограничение операций может привести к их взаимной блокировке.
Управление доступом к ресурсам. Если операции получают доступ к общему ресурсу одновременно, возникает необходимость в том, чтобы они обращались к общему ресурсу в определенном порядке, например, объект не может быть удален из структуры данных до тех пор, пока данный объект не будет добавлен в некоторую другую структуру данных.
В табл. 8.5 представлены основные типы паттернов параллельного программирования и их назначение.
Таблица 8.5
Основные типы паттернов параллельного программирования
Типы паттернов параллельного программирования
| Назначение
| Однопоточное выполнение (Single Threaded Execution)
| Данный паттерн – это ключевой паттерн данной группы. Большинство задач, связанных с управлением доступа к разделяемым ресурсам, можно решить посредством использования данного паттерна.
| Охраняемая приостановка (Guarded Suspention)
| Используется в том случае, когда поток имеет монопольный доступ к разделяемому ресурсу и оказывается, что он не может завершить выполнение операции над этим ресурсом, поскольку не имеет доступа к другим ресурсам.
| Объект блокировки (Lock Object)
| Используется в том случае, когда требуется координировать доступ к нескольким ресурсам.
| Отмена (Balking)
| Используется в том случае, когда операция должна быть выполнена либо немедленно, либо никогда.
| Планировщик (Scheduler)
| Используется в ситуациях, когда важен порядок выполнения операций. Этот паттерн известен также под именем Диспетчер (Scheduler).
| Блокировка чтения/записи (Read/Write Lock)
| Обеспечивает альтернативный доступ к ресурсам, в случае, если одни операции могут совместно использовать тот или иной ресурс одновременно, а другие этого делать не могут.
| Производитель-потребитель (Producer/consumer)
| Позволяет координировать объекты, создающие некоторый ресурс, и объекты, использующие этот ресурс.
| Двухфазное завершение (Two-Phase Termination)
| Применяется для правильного последовательного закрытия потоков.
| Двойная буферизация (Double Buffering)
| Представляет собой специальную версию паттерна Производитель-потребитель. Этот паттерн позволяет создавать необходимый ресурс заранее.
| Асинхронная обработка (Asynchronous Processing)
| Позволяет избежать ожидания результатов операции, если этот результат не нужен немедленно.
| Будущее (Future)
| Позволяет классам, вызывающим операцию, не знать о том, является ли данная операция синхронной или асинхронной.
| Для разных типов паттернов могут использоваться разные способы описания. Чаще всего используется описание, предложенное в [125], в соответствии с которым полное описание паттерна выглядит следующим образом:
1. Название и тип.
2. Назначение.
3. Другие названия (если имеются).
4. Мотивация – какие проблемы можно решить с помощью данного паттерна.
5. Условия, при которых целесообразно применять данный паттерн.
6. Структура паттерна (в объектно-ориентированной нотации).
7. Объекты и паттерны, используемые в данном паттерне.
8. Результаты работы паттерна.
9. Рекомендации по применению.
10. Пример кода.
11. Примеры использования.
12. Родственные паттерны.
Как указывалось выше, паттерны – это классы проверенных практикой проектных решений, использование которых приводит к положительным результатам.
8.6. Антипаттерны
Антипаттерны (antipatterns), также известные как ловушки (pitfalls) — это классы наиболее часто внедряемых плохих решений проблем. Они изучаются, как категория, в случае, когда их хотят избежать в будущем, и некоторые отдельные случаи их могут быть распознаны при изучении неработающих систем [127].
Частью хорошей практики программирования является избегание антипаттернов.
Данная концепция также прекрасно подходит к машиностроению, строительству и другим областям. Несмотря на то, что термин нечасто используется вне программной инженерии, концепция является универсальной.
Следует отметить, что общепринятой классификации антипаттернов не существует. Применительно к ИС можно выделить следующие типовые группы антипаттернов: антипаттерны в управлении разработкой ПО, антипаттерны в разработке ПО, антипаттерны в объектно-ориентированном программировании, методологические и организационные антипаттерны.
В таблице 8.6 преставлены наиболее популярные антипаттерны в управлении разработкой ПО и их свойства. Таблица 8.6
Наиболее популярные антипаттерны в управлении разработкой ПО
Типы антипаттернов в управлении разработкой ПО
| Свойства
| Дым и зеркала (Smoke and mirrors)
| Демонстрация того, как будут выглядеть ненаписанные функции. Название происходит от двух излюбленных способов, которыми фокусники скрывают свои секреты.
| Раздувание ПО (Software bloat).
| Разрешение последующим версиям системы требовать всё больше и больше ресурсов.
| Функции для галочки
| Превращение программы в конгломерат плохо реализованных и не связанных между собой функций (как правило, для того, чтобы заявить в рекламе, что функция есть).
| В таблице 8.7 представлены антипаттерны в области разработки ПО и их свойства.
Таблица 8.7
Антипаттерны в области разработки ПО и их свойства
Типы антипаттернов в области разработки ПО
| Свойства
| Неопределённая точка зрения (Ambiguous viewpoint)
| Представление модели без спецификации её точки рассмотрения.
| Большой комок грязи (Big ball of mud)
| Система с нераспознаваемой структурой.
| Бензиновая фабрика (Gas factory)
| Необязательная сложность дизайна.
| Затычка на ввод данных (Input kludge)
| Забывчивость в спецификации и выполнении поддержки возможного неверного ввода.
| Раздувание интерфейса (Interface bloat)
| Изготовление интерфейса очень мощным и очень трудным для осуществления.
| Магическая кнопка (Magic pushbutton)
| Выполнение результатов действий пользователя в виде неподходящего (недостаточно абстрактного) интерфейса.
| Перестыковка (Re-Coupling)
| Процесс внедрения ненужной зависимости.
| Дымоход (Stovepipe system)
| Редко поддерживаемая сборка плохо связанных компонентов.
| Гонки (Race condition)
| Непредвидение возможности наступления событий в порядке, отличном от ожидаемого.
| В таблице 8.8 представлены антипаттерны в области объектно-ориентированного программирования и их свойства.
Таблица 8.8
Антипаттерны в области объектно-ориентированного программирования
Типы антипаттернов в области объектно-ориентированного программирования
| Свойства
| Базовый класс-утилита (BaseBean)
| Наследование функциональности из класса-утилиты вместо делегирования к нему.
| Вызов предка (CallSuper)
| Для реализации прикладной функциональности методу класса-потомка требуется в обязательном порядке вызывать те же методы класса-предка.
| Божественный объект (God object)
| Концентрация слишком большого количества функций в одной части системы (классе).
| Полтергейст (Poltergeist)
| Объекты, чьё единственное предназначение — передавать информацию другим объектам.
| Проблема йо-йо (Yo-yo problem)
| Чрезмерная размытость сильно связанного кода (например, выполняемого по порядку) по иерархии классов.
| Синглетонизм (Singletonitis)
| Избыточное использование паттерна Одиночка.
| В табл. 8.9 преставлены антипаттерны в области программирования и их свойства.
Таблица 8.9
Антипаттерны в области программирования
Типы антипаттернов в области программирования
| Свойства
| Ненужная сложность (Accidental complexity)
| Внесение ненужной сложности в решение.
| Действие на расстоянии (Action at a distance)
| Неожиданное взаимодействие между широко разделёнными частями системы.
| Накопить и запустить (Accumulate and fire)
| Установка параметров подпрограмм в наборе глобальных переменных.
| Лодочный якорь (Boat anchor)
| Сохранение более не используемой части системы.
| Активное ожидание (Busy spin)
| Потребление ресурсов центрального процессора во время ожидания события, обычно при помощи постоянно повторяемой проверки, вместо того, чтобы использовать систему сообщений.
| Кэширование ошибки (Caching failure)
| Забывать сбросить флаг ошибки после её обработки.
| Инерция кода (Code momentum)
| Сверхограничение части системы путём постоянного подразумевания её поведения в других частях системы
Кодирование путём исключения (Coding by exception): Добавление нового кода для поддержки каждого специального распознанного случая.
| Таинственный код (Cryptic code)
| Использование аббревиатур вместо мнемоничных имён.
| Жёсткое кодирование (Hard code)
| Внедрение предположений об окружении системы в слишком большом количестве точек её реализации.
| Мягкое кодирование (Soft code)
| Патологическая боязнь жёсткого кодирования, приводящая к тому, что настраивается всё что угодно, при этом конфигурирование системы само по себе превращается в программирование.
| Поток лавы (Lava flow)
| Сохранение нежелательного (излишнего или низкокачественного) кода по причине того, что его удаление слишком дорого или будет иметь непредсказуемые последствия.
| Магические числа (Magic numbers)
| Включение в алгоритмы чисел без объяснений их смысла.
| Процедурный код (Procedural code)
| Когда другая парадигма является более подходящей.
| Спагетти-код (Spaghetti code)
| Код с чрезмерно запутанным порядком выполнения.
| Мыльный пузырь (Soap bubble)
| Класс, инициализированый мусором, максимально долго притворяется, что содержит какие-то данные.
| В табл. 8.10 представлены методологические антипаттерны и их свойства.
Таблица 8.10
Методологические антипаттерны и их свойства
Типы методологических антипаттернов
| Свойства
| Программирование методом копирования-вставки (Copy and paste programming)
| Копирование (и лёгкая модификация) существующего кода вместо создания общих решений.
| Дефакторинг (De-Factoring)
| Процесс уничтожения функциональности и замены её документацией.
| Золотой молоток (Golden hammer)
| Сильная уверенность в том, что любимое решение универсально применимо. Название происходит от английской поговорки «когда в руках молоток, все проблемы кажутся гвоздями».
| Фактор невероятности (Improbability factor)
| Предположение о невозможности того, что сработает известная ошибка.
| Преждевременная оптимизация (Premature optimization)
| Оптимизация на основе недостаточной информации.
| Изобретение колеса (Reinventing the wheel)
| Ошибка адаптации существующего решения.
| Изобретение квадратного колеса (Reinventing the square wheel)
| Создание плохого решения, когда существует хорошее.
| В табл. 8.11 преставлены примеры организационных антипаттернов и их свойства.
Таблица 8.11
Организационные антипаттерны и их свойства
Типы методологических антипаттернов
| Свойства
| Аналитический паралич (Analysis paralysis)
| Выделение непропорционально больших усилий в фазе анализа проекта.
| Дойная корова (Cash cow)
| Закрытый продукт, приносящий выгоду, часто ведёт к самоуспокоенности относительно новых продуктов.
| Продолжительное устаревание (Continuous obsolescence)
| Выделение непропорционально больших усилий портированию системы в новые окружения.
| Сваливание расходов (Cost migration)
| Перенос расходов на проект к уязвимому отделу или бизнес-партнёру.
| Ползущий улучшизм (Creeping featurism)
| Добавление новых улучшений в ущерб качеству системы.
| Разработка комитетом (Design by committee)
| Результат того, что имеется много содействующих разработке, но не имеется единого видения.
| Эскалация обязательств (Escalation of commitment)
| Продолжение реализации решения в том случае, когда неправильность его доказана.
| Я тебе это говорил (I told you so)
| Когда игнорируется предупреждение эксперта, являющееся оправданным.
| Управление основанное на числах (Management by numbers)
| Уделяется избыточное внимание численным критериям управления, когда они неважны или стоимость их получения слишком высока.
| Драконовские меры (Management by perkele)
| Жёстко авторитарный стиль управления, в том случае, когда он не оправдан.
| Управление грибами (Mushroom management)
| Удержание работников в неинформированном и занятом состоянии.
| Расползание рамок (Scope creep)
| Дозволение рамкам проекта расти без должного контроля.
| Замкнутость на продавце (Vendor lock-in)
| Изготовление системы, жёстко привязанной к одному поставщику.
| Единственный знающий человек (Single head of knowledge)
| Единственный человек во всей организации контролирует жизненно-важную область ноу-хау или информации о внутренностях системы. Система оказывается "завязана" на этого человека. При его уходе или бездействии работа останавливается.
| Рыцарь на белом коне (Knight in shining armor)
| Личность, которая не совершает ошибок, появляется на сцене и пытается починить всё, без сообщений о том, какие изменения он сделал или сделает и почему он их делает.
|
Контрольные вопросы
1. Дайте определение понятий паттерн.
2. Приведите классификацию паттернов.
3. Перечислите и охарактеризуйте основные структурные паттерны.
4. Определите понятие архитектурный паттерн.
5. Перечислите и охарактеризуйте основные паттерны параллельного программирования.
6. Что такое антипаттерны?
7. Приведите классификацию антипаттернов.
|
|
|