Чем отличается работа опытного проектировщика программного обеспечения от работы новичка? Имеющийся у эксперта опыт позволяет ему аккуратнее определять задачи, которые необходимо решить, точнее выделять среди них наиболее важные и менее значимые, четче представлять ограничения, в рамках которых должна работать будущая система. Но важнее всего то, что эксперт отличается накопленными знаниями о приемлемых или неприемлемых в определенных ситуациях решениях, о свойствах программных систем, обеспечиваемых ими, и способностью быстро подготовить качественное решение сложной проблемы, опираясь на эти знания.
Давней мечтой преподавателей всех дисциплин является выделение таких знаний "в чистом виде" и эффективная передача их следующим поколениям специалистов. В области проектирования сложных систем на роль такого представления накопленного опыта во второй половине XX века стали претендовать
На основе имеющегося опыта исследователями и практиками разработки ПО выделено множество образцов — типовых архитектур, проектных решений для отдельных подсистем и модулей или просто программистских приемов, — позволяющих получить достаточно качественные решения типовых задач, а не изобретать каждый раз велосипед.
Более того, люди, наиболее активно вовлеченные в поиск
Образец (pattern) представляет собой шаблон решения типовой, достаточно часто встречающейся задачи в некотором контексте, т.е. при некоторых ограничениях на ожидаемые решения и определенном наборе требований к ним.
В качестве примера рассмотрим такую ситуацию. Мы разработали большую программу из многих модулей. Так сложилось, что почти все они опираются на некоторый
Другим примером такой ситуации является разработка набора тестов для некоторых операций. Хотелось бы, чтобы с помощью этого набора можно было бы тестировать любую возможную реализацию функций, выполняемых этими операциями. Если функции достаточно часто встречаются, например, совместно реализуют очередь, хранящую некоторые элементы, то такая возможность очень полезна. Но у каждого набора операций может быть свой интерфейс, переделывать все тесты под который слишком трудоемко.
Если можно представить набор требуемых операций как интерфейс некоторого класса в объектно-ориентированном языке программирования, достойно выйти из такой ситуации поможет
(рис 7.1) Структура классов-участников образца "адаптер"Предлагаемое решение состоит в следующем. Операции, которые необходимы для работы нашей системы, называемой клиентом, объединяются в некоторый класс или интерфейс (называемый целевым ), и система пишется так, что она работает с объектом этого типа и его операциями. Получив реализацию тех же функций с отличающимися именами и типами параметров, мы определяем адаптер — класс-наследник целевого класса (или реализующий соответствующий интерфейс), в котором перегружаем нужные нам операции, выражая их через имеющуюся реализацию. При этом каждый раз объем дополнительной работы достаточно мал (если, конечно, полученная реализация действительно реализует нужные функции), а код клиента остается неизменным.
По типу решаемых задач выделяют следующие разновидности образцов.
Они представляют собой типовые решения при моделировании сложных взаимоотношений между понятиями некоторой предметной области. Обычно они являются представлением этих понятий и отношений между ними с помощью набора классов и их связей, подходящего для любого объектно-ориентированного языка. Такие представления обладают важными атрибутами качественных модельных решений — способностью отображать понятным образом большое многообразие ситуаций, возникающих в реальной жизни, отсутствием необходимости вносить изменения в модель при небольших изменениях в требованиях к основанному на ней программному обеспечению и удобством внесения изменений, вызванных естественными изменениями в понимании моделируемых понятий. В частности, небольшое расширение данных, связанных с некоторым понятием, приводит к небольшим изменениям в структуре, чаще всего, лишь одного класса модели.
В отличие от X класса концептуальной модели в реализации может остаться полем, а может превратиться в пару методов getX() и setX() или в один метод getX() (т.е. в свойство, property, в терминах C# и
Такие образцы представляют собой типовые способы организации системы в целом или крупных подсистем, задающие некоторые правила
Они определяют
Образцы этого типа описывают успешные практики организации разработки ПО или другой сложной деятельности, позволяющие решать определенные задачи в рамках некоторого контекста, который включает ограничения на возможные решения.
Для описания образцов были выработаны определенные шаблоны. Далее мы будем использовать один из таких шаблонов для описания
Далее в этой лекции рассматриваются некоторые из известных образцов в соответствии с приведенной классификацией. Другие образцы будут упоминаться в последующих лекциях при рассмотрении способов решения тех или иных задач, а также библиотек языков Java и C#.
В качестве примера
Наиболее простым образцом этой группы является образец величина (quantity). Результаты большинства измерений имеют количественное выражение, однако, если представлять их в виде атрибутов числовых типов (рост — 182, вес — 83), часть информации пропадает. Пока все пользователи системы и разработчики, вносящие в нее изменения, помнят, в каких единицах измеряются все хранимые величины все в порядке, но стоит хоть одному ошибиться — и последствия могут быть весьма серьезны. Такого рода ошибка в 1998 году вывела из строя американский космический аппарат Mars Climate Orbiter, предназначавшийся для исследования климата Марса. Данные о текущих параметрах движения аппарата поступали на Землю, обрабатывались, и результирующие команды отправлялись обратно. При этом процедуры мониторинга и управления движением на самом аппарате воспринимали величину импульса как измеренную в Ньютонах на секунду, а программы обработки данных на Земле — как значение импульса в фунтах силы на секунду. В итоге это привело к выходу на гораздо более низкую, чем планировалось, орбиту, потере управления и гибели аппарата стоимостью около 130 миллионов долларов [4].
Поэтому более аккуратное решение — использовать для хранения данных числовых измерений объекты специального класса , в полях которого хранится не только значение величины, но и единица ее измерения. Кроме того, весьма полезно определить операции сложения, вычитания и сравнения таких величин.
(рис 7.2) Класс для представления величин, имеющих разные единицы измеренияПомимо измерений, использовать такое представление удобно и для сумм денег в финансовых системах. Аналогом единиц измерения в этом случае выступают различные валюты. От физических величин валюты отличаются изменяемым отношением, с помощью которого их можно переводить одну в другую. Это отношение может зависеть от времени. Кроме того, существуют единицы измерения физических величин, которые преобразуются друг в друга более сложным, чем умножение на некоторое число, способом — например, градусы по Фаренгейту и по Цельсию.
Эти примеры могут быть охвачены образцом преобразование, который позволяет представлять в системе правила преобразования различных единиц измерения друг в друга. Для большинства преобразований достаточно величины отношения между единицами, быть может, зависящего от времени, поэтому стоит выделить класс для хранения этого отношения.
(рис 7.3) Представление возможных преобразований между единицами измеренийДругой тип связи между различными единицами измерения — так называемые составные единицы, например Ньютон для измерения силы (1 Н = 1 кг*м/с2). Разрешение подобного рода соотношений может быть реализовано, если определить два подкласса класса Unit — один для представления простых единиц, PrimeUnit, другой для представления составных, CompoundUnit, и определить две связи, сопоставляющие одной составной единице два
(рис 7.4) Представление составных единиц измеренийВ медицине, где хранение данных измерений имеет особое значение, измерения почти всегда связываются с пациентом, для которого они производились. К тому же, медицинских измерений, имеющих, например, значение длины, очень много. Для того чтобы различать оба этих атрибута измерения — объект измерения и вид измерения (например, пациент Иванов Петр Сергеевич и окружность его талии), — их нужно явно ввести в модель. Так возникает образец измерение. Этот образец становится полезным, если имеется очень много различных измерений для каждого объекта, группируемых в достаточно много видов измеряемых явлений.
(рис 7.5) Набор классов для представления результатов измеренийБывает, однако, необходимо вести учет не только количественных измерений, но и качественных наблюдений, результат которых представляется не числом, а некоторым значением перечислимого типа (группа крови II, ожог 3-й степени и пр.). При этом наблюдения очень похожи на измерения: относятся к некоторому объекту и определяют некоторое значение для какого-то вида наблюдений.
Для совместного представления результатов наблюдений и измерений можно использовать шаблон наблюдение, структура классов которого показана на рис. 7.6. Требуется некоторая привычка, чтобы быстро разложить по этим классам какой-нибудь реальный пример. Например, группа крови — вид явлений, II — явление этого вида, наблюдение заключается в том, что у Петра Сергеевича Иванова была обнаружена именно такая группа крови. Эти усилия, однако, с лихвой окупаются огромным количеством фактов, которые без изменений можно уложить в эту схему.
(рис 7.6) Набор классов для представления результатов как измерений, так и наблюденийРабота по выделению и классификации
| Виды стилей и конкретные стили | Контекст использования и основные решения | Примеры | |
|---|---|---|---|
| Конвейер обработки данных (data flow) | Система выдает четко определенные выходные данные в результате обработки четко определенных входных данных, при этом процесс обработки не зависит от времени, применяется многократно, одинаково к любым данным на входе. Обработка организуется в виде набора (необязательно последовательности) отдельных компонентов-обработчиков, передающих свои результаты на вход другим обработчикам или на выход всей системы. Важными свойствами являются четко определенная структура данных и возможность интеграции с другими системами |
||
| Пакетная обработка (batch |
Один-единственный вывод производится на основе чтения некоторого одного набора данных на входе, промежуточные преобразования организуются в виде последовательности | Сборка программной системы: компиляция, сборка системы, сборка документации, выполнение тестов | |
| Каналы и фильтры (pipe-and-filter) | Нужно обеспечить преобразование непрерывных потоков данных. При этом преобразования инкрементальны и следующее может быть начато до окончания предыдущего. Имеется, возможно, несколько входов и несколько выходов. В дальнейшем возможно добавление дополнительных преобразований |
Утилиты UNIX | |
| Замкнутый цикл управления ( |
Нужно обеспечить обработку постоянно поступающих событий в плохо предсказуемом окружении. Используется общий диспетчер событий, который классифицирует событие и отдает его на асинхронную обработку обработчику событий такого типа, после чего диспетчер снова готов воспринимать события |
Встроенные системы управления в автомобилях, авиации, спутниках. Обработка запросов на сильно загруженных Web-серверах. Обработка действий пользователя в GUI |
|
| Вызов-возврат (call-return) | Порядок выполнения действий четко определен, отдельные компоненты не могут выполнять полезную работу, не получая обращения от других | ||
| Процедурная декомпозиция | Данные неизменны, процедуры работы с ними могут немного меняться, могут возникать новые. Выделяется набор процедур, схема передачи управления между которыми представляет собой дерево с основной процедурой в его корне |
Основная схема построения программ для языков C, Pascal, Ada | |
| Абстрактные типы данных ( |
В системе много данных, структура которых может меняться. Важны возможности внесения изменений и интеграции с другими системами. Выделяется набор абстрактных типов данных, каждый из которых предоставляет набор операций для работы с данными такого типа. Внутреннее представление данных скрывается |
Библиотеки классов и компонентов | |
| Многоуровне-вая система (layers) | Имеется естественное расслоение задач системы на наборы задач, которые можно было бы решать последовательно — сначала задачи первого уровня, затем, используя полученные решения, — второго, и т.д. Важны переносимость и возможность многократного использования отдельных компонентов. Компоненты разделяются на несколько уровней таким образом, что компоненты данного уровня могут использовать для своей работы только соседей или компоненты предыдущего уровня. Могут быть более слабые ограничения, например, компонентам верхних уровней разрешено использовать компоненты всех нижележащих уровней |
Телекоммуникацион-ные протоколы в модели OSI (7 уровней), реальные протоколы сетей передачи данных (обычно 5 уровней или меньше). Системы автоматизации предприятий (уровни интерфейса пользователя–обработки запросов–хранения данных) |
|
| Клиент-сервер | Решаемые задачи естественно распределяются между инициаторами и обработчиками запросов, возможно изменение внешнего представления данных и способов их обработки | Основная модель бизнес-приложений: клиентские приложения, воспринимающие запросы пользователей и сервера, выполняющие эти запросы | |
| Интерактивные системы | Необходимость достаточно быстро реагировать на действия пользователя, изменчивость пользовательского интерфейса | ||
| Данные–представление–обработка (model–view-controller, MVC) | Изменения во внешнем представлении достаточно вероятны, одна и та же информация представляется по-разному в нескольких местах, система должна быстро реагировать на изменения данных. Выделяется набор компонентов, ответственных за хранение данных, компоненты, ответственные за их представления для пользователей, и компоненты, воспринимающие команды, преобразующие данные и обновляющие их представления |
Наиболее часто используется при построении приложений с GUI. Document-View в MFC (Microsoft Foundation Classes) — документ в этой схеме объединяет роли данных и обработчика |
|
| Представление–абстракция–управление (presentation–abstraction–control) | Интерактивная система на основе агентов, имеющих собственные состояния и пользовательский интерфейс, возможно добавление новых агентов. Отличие от предыдущей схемы в том, что для каждого отдельного набора данных его модель, представление и управляющий компонент объединяются в агента, ответственного за всю работу именно с этим набором данных. Агенты взаимодействуют друг с другом только через четко определенную часть интерфейса управляющих компонентов |
||
| Системы на основе хранилища данных | Основные функции системы связаны с хранением, обработкой и представлением больших количеств данных | ||
| Репозиторий ( |
Порядок работы определяется только потоком внешних событий. Выделяется общее хранилище данных — репозиторий. Каждый обработчик запускается в ответ на соответствующее ему событие и как-то преобразует часть данных в репозитории |
Среды разработки и |
|
| Классная доска (blackboard) | Способ решения задачи в целом неизвестен или слишком трудоемок, но известны методы, частично решающие задачу, композиция которых способна выдавать приемлемые результаты, возможно добавление новых потребителей данных или обработчиков. Отдельные обработчики запускаются, только если данные репозитории для их работы подготовлены. Подготовленность данных определяется с помощью некоторой системы шаблонов. Если можно запустить несколько обработчиков, используется система их приоритетов |
||
Многие из представленных стилей носят достаточно общий характер и часто встречаются в разных системах. Кроме того, часто можно обнаружить, что в одной системе используются несколько
Более подробного рассмотрения заслуживают
Название. Каналы и фильтры (pipes and filters).
Назначение. Организация обработки потоков данных в том случае, когда процесс обработки распадается на несколько шагов. Эти шаги могут выполняться отдельными обработчиками, возможно, реализуемыми разными разработчиками или даже организациями. При этом нужно принимать во внимание следующие факторы:
Действующие силы.
Решение. Каждая отдельная задача по обработке данных разбивается на несколько мелких шагов. Выходные данные одного шага являются входными для других. Каждый шаг реализуется специальным компонентом — фильтром (filter). Фильтр потребляет и выдает данные инкрементально, небольшими порциями. Передача данных между фильтрами осуществляется по каналам (pipes).
Структура. Основными ролями компонентов в рамках данного стиля являются фильтр и канал. Иногда выделяют специальные виды фильтров — источник данных (data source) и потребитель данных (data sink), которые, соответственно, только выдают данные или только их потребляют. Каждый поток обработки данных состоит из чередующихся фильтров и каналов, начинается источником данных и заканчивается их потребителем.
Фильтр получает на свой вход данные и обрабатывает их, дополняя их результатами обработки, удаляя какие-то части и трансформируя их в некоторое другое представление. Иногда фильтр сам требует входные данные и выдает выходные по их получении, иногда он, наоборот, может реагировать на события прихода данных на вход и требования данных на выходе. Фильтр обычно потребляет и выдает данные некоторыми порциями.
(рис 7.7) Пример структуры классов для образца каналы и фильтрыКанал обеспечивает передачу данных, их буферизацию и синхронизацию обработки их соседними фильтрами (например, если оба соседних фильтра активны, работают в параллельных процессах). Если никакой дополнительный буферизации и синхронизации не требуется, канал может представлять собой простую передачу данных в виде параметра или результата вызова операции.
На рис. 7.7 показан пример диаграммы классов для данного образца, в котором 3 канала реализованы неявно — через вызовы операций и возвращение результатов, а один — явно. Из участвующих в этом примере фильтров источник и потребитель данных, а также Filter 1 запрашивают входные данные, Filter 3 сам передает их дальше, а Filter 2 и запрашивает, и передает данные самостоятельно.
(рис 7.8) Сценарий работы проталкивающего фильтраДинамика. Возможны три различных сценария работы одного фильтра — проталкивание данных (push model, фильтр сам передает данные следующему компоненту, а получает их только в результате передачи предыдущего), вытягивание данных (pull model, фильтр требует данные у предыдущего компонента, следующий сам должен затребовать данные у него) и смешанный вариант. Часто реализуется только один вид передачи данных для всех фильтров в рамках системы. Кроме того, канал может буферизовать данные и синхронизовать взаимодействующие с ним фильтры. Сценарии работы системы в целом строятся в виде различных комбинаций вариантов работы отдельных фильтров.

(рис 7.10) Сценарий работы вытягивающего фильтра(рис 7.9) Сценарий работы буферизующего и синхронизующего каналаРеализация. Основные шаги реализации следующие:
Могут быть выделены специальные каналы для передачи сообщений об ошибках.
При возникновении ошибок ввода соответствующий фильтр может игнорировать дальнейшие входные данные до получения определенного разделителя, гарантирующего, что после него идут данные, не связанные с предыдущими.
Следствия применения образца.
Достоинства:
Недостатки:
Примеры. Наиболее известный пример использования данного образца — система утилит UNIX [8], пополненная возможностями оболочки (shell) по организации каналов между процессами. Большинство утилит могут играть роль фильтров при обработке текстовых данных, а каналы строятся при помощи соединения стандартного ввода одной программы со стандартным выводом другой.
Другим примером может служить часто используемая архитектура компилятора как последовательности фильтров, обрабатывающих входную программу — лексического анализатора (лексера), синтаксического анализатора (парсера), семантического анализатора, набора оптимизаторов и генератора результирующего кода. Таким способом можно достаточно быстро построить прототипный компилятор для несложного языка. Более производительные компиляторы, нацеленные на промышленное использование, строятся по более сложной схеме, в частности, используя элементы стиля "Репозиторий".
Название. Многоуровневая система (layers).
Назначение. Реализация больших систем, которые имеют большое количество разноплановых элементов, использующих друг друга. Некоторые аспекты работы таких систем могут включать в себя много операций, выполняемых разными компонентами на разных уровнях (т.е. одна задача решается за счет последовательных обращений между элементами разных уровней, другая — тоже, но участвующие в решении этих задач элементы могут быть различны). При этом нужно принимать во внимание следующие факторы:
Действующие силы.
Решение. Выделяется некоторый набор уровней, каждый из которых отвечает за решение своих собственных подзадач. Для этого он использует интерфейс, предоставляемый предыдущим уровнем, предоставляя, в свою очередь, некоторый интерфейс для следующего уровня.
Каждый отдельный уровень может быть в дальнейшем декомпозирован на более мелкие компоненты.
Структура. Основными компонентами являются уровни. Иногда выделяют клиентов, использующих интерфейс самого верхнего уровня. Каждый уровень предоставляет интерфейс для решения определенного множества задач. Сам он решает их, опираясь на интерфейс предшествующего уровня.
На каждом уровне может находиться много более мелких компонентов.
(рис 7.11) Пример структуры многоуровневой системы.Классы для уровней условные, они обычно декомпозируются на наборы более мелких компонентов
Динамика. Сценарии работы системы могут быть получены компоновкой следующих четырех. Часто в виде многих уровней реализуются коммуникационные системы, две такие системы могут взаимодействовать через самый нижний уровень — при этом пара симметричных сценариев (по подъему–спуску обращений) выполняется в рамках одного общего сценария на разных машинах.
(рис 7.12) Составной сценарий пересылки сообщения по сетиРеализация. Основные шаги реализации следующие:
Следствия применения образца.
Достоинства:
Недостатки:
Примеры. Наиболее известный пример использования данного образца — стандартная модель протоколов связи открытых систем (Open System Interconnection, OSI) [9]. Она состоит из 7 уровней:
Модель OSI оказалась все же слишком сложна для использования на практике. Сейчас наиболее широко применяемые наборы протоколов строятся по урезанной схеме OSI — в ней отсутствуют пятый и шестой уровни, прикладные протоколы пользуются непосредственно службами протоколов транспортного уровня.
Другой пример многоуровневой архитектуры — архитектура современных информационных систем или систем автоматизации бизнеса. Она включает следующие уровни [3]:
Чаще всего этот уровень рассматривается как интерфейс пользователя. В его рамках определяется представление данных для передачи другим системам или пользователям, набор экранов, форм и отчетов, с которыми имеют дело пользователи.
На нем находятся все ресурсы, которыми пользуется система, в том числе другие системы. Очень часто используемые ресурсы сводятся к набору баз данных, необходимых для работы организации. На этом уровне определяется структура используемых ресурсов и способы управления ими, в частности, конкретное размещение данных по таблицам реляционной базы данных или классам объектной базы данных и соответствующий набор индексов. Чаще всего схемы баз данных оптимизируются под конкретный набор запросов, и поэтому их структура несколько отличается от концептуальной схемы данных, находящейся на предыдущем уровне.
Часто два средних уровня объединяются в один — уровень функционирования приложений, что дает в результате широко используемую трехзвенную архитектуру информационных систем.
Чем отличается работа опытного проектировщика программного обеспечения от работы новичка? Имеющийся у эксперта опыт позволяет ему аккуратнее определять задачи, которые необходимо решить, точнее выделять среди них наиболее важные и менее значимые, четче представлять ограничения, в рамках которых должна работать будущая система. Но важнее всего то, что эксперт отличается накопленными знаниями о приемлемых или неприемлемых в определенных ситуациях решениях, о свойствах программных систем, обеспечиваемых ими, и способностью быстро подготовить качественное решение сложной проблемы, опираясь на эти знания.
Давней мечтой преподавателей всех дисциплин является выделение таких знаний "в чистом виде" и эффективная передача их следующим поколениям специалистов. В области проектирования сложных систем на роль такого представления накопленного опыта во второй половине XX века стали претендовать
На основе имеющегося опыта исследователями и практиками разработки ПО выделено множество образцов — типовых архитектур, проектных решений для отдельных подсистем и модулей или просто программистских приемов, — позволяющих получить достаточно качественные решения типовых задач, а не изобретать каждый раз велосипед.
Более того, люди, наиболее активно вовлеченные в поиск
Образец (pattern) представляет собой шаблон решения типовой, достаточно часто встречающейся задачи в некотором контексте, т.е. при некоторых ограничениях на ожидаемые решения и определенном наборе требований к ним.
В качестве примера рассмотрим такую ситуацию. Мы разработали большую программу из многих модулей. Так сложилось, что почти все они опираются на некоторый
Другим примером такой ситуации является разработка набора тестов для некоторых операций. Хотелось бы, чтобы с помощью этого набора можно было бы тестировать любую возможную реализацию функций, выполняемых этими операциями. Если функции достаточно часто встречаются, например, совместно реализуют очередь, хранящую некоторые элементы, то такая возможность очень полезна. Но у каждого набора операций может быть свой интерфейс, переделывать все тесты под который слишком трудоемко.
Если можно представить набор требуемых операций как интерфейс некоторого класса в объектно-ориентированном языке программирования, достойно выйти из такой ситуации поможет
(рис 7.1) Структура классов-участников образца "адаптер"Предлагаемое решение состоит в следующем. Операции, которые необходимы для работы нашей системы, называемой клиентом, объединяются в некоторый класс или интерфейс (называемый целевым ), и система пишется так, что она работает с объектом этого типа и его операциями. Получив реализацию тех же функций с отличающимися именами и типами параметров, мы определяем адаптер — класс-наследник целевого класса (или реализующий соответствующий интерфейс), в котором перегружаем нужные нам операции, выражая их через имеющуюся реализацию. При этом каждый раз объем дополнительной работы достаточно мал (если, конечно, полученная реализация действительно реализует нужные функции), а код клиента остается неизменным.
По типу решаемых задач выделяют следующие разновидности образцов.
Они представляют собой типовые решения при моделировании сложных взаимоотношений между понятиями некоторой предметной области. Обычно они являются представлением этих понятий и отношений между ними с помощью набора классов и их связей, подходящего для любого объектно-ориентированного языка. Такие представления обладают важными атрибутами качественных модельных решений — способностью отображать понятным образом большое многообразие ситуаций, возникающих в реальной жизни, отсутствием необходимости вносить изменения в модель при небольших изменениях в требованиях к основанному на ней программному обеспечению и удобством внесения изменений, вызванных естественными изменениями в понимании моделируемых понятий. В частности, небольшое расширение данных, связанных с некоторым понятием, приводит к небольшим изменениям в структуре, чаще всего, лишь одного класса модели.
В отличие от X класса концептуальной модели в реализации может остаться полем, а может превратиться в пару методов getX() и setX() или в один метод getX() (т.е. в свойство, property, в терминах C# и
Такие образцы представляют собой типовые способы организации системы в целом или крупных подсистем, задающие некоторые правила
Они определяют
Образцы этого типа описывают успешные практики организации разработки ПО или другой сложной деятельности, позволяющие решать определенные задачи в рамках некоторого контекста, который включает ограничения на возможные решения.
Для описания образцов были выработаны определенные шаблоны. Далее мы будем использовать один из таких шаблонов для описания
Далее в этой лекции рассматриваются некоторые из известных образцов в соответствии с приведенной классификацией. Другие образцы будут упоминаться в последующих лекциях при рассмотрении способов решения тех или иных задач, а также библиотек языков Java и C#.
В качестве примера
Наиболее простым образцом этой группы является образец величина (quantity). Результаты большинства измерений имеют количественное выражение, однако, если представлять их в виде атрибутов числовых типов (рост — 182, вес — 83), часть информации пропадает. Пока все пользователи системы и разработчики, вносящие в нее изменения, помнят, в каких единицах измеряются все хранимые величины все в порядке, но стоит хоть одному ошибиться — и последствия могут быть весьма серьезны. Такого рода ошибка в 1998 году вывела из строя американский космический аппарат Mars Climate Orbiter, предназначавшийся для исследования климата Марса. Данные о текущих параметрах движения аппарата поступали на Землю, обрабатывались, и результирующие команды отправлялись обратно. При этом процедуры мониторинга и управления движением на самом аппарате воспринимали величину импульса как измеренную в Ньютонах на секунду, а программы обработки данных на Земле — как значение импульса в фунтах силы на секунду. В итоге это привело к выходу на гораздо более низкую, чем планировалось, орбиту, потере управления и гибели аппарата стоимостью около 130 миллионов долларов [4].
Поэтому более аккуратное решение — использовать для хранения данных числовых измерений объекты специального класса , в полях которого хранится не только значение величины, но и единица ее измерения. Кроме того, весьма полезно определить операции сложения, вычитания и сравнения таких величин.
(рис 7.2) Класс для представления величин, имеющих разные единицы измеренияПомимо измерений, использовать такое представление удобно и для сумм денег в финансовых системах. Аналогом единиц измерения в этом случае выступают различные валюты. От физических величин валюты отличаются изменяемым отношением, с помощью которого их можно переводить одну в другую. Это отношение может зависеть от времени. Кроме того, существуют единицы измерения физических величин, которые преобразуются друг в друга более сложным, чем умножение на некоторое число, способом — например, градусы по Фаренгейту и по Цельсию.
Эти примеры могут быть охвачены образцом преобразование, который позволяет представлять в системе правила преобразования различных единиц измерения друг в друга. Для большинства преобразований достаточно величины отношения между единицами, быть может, зависящего от времени, поэтому стоит выделить класс для хранения этого отношения.
(рис 7.3) Представление возможных преобразований между единицами измеренийДругой тип связи между различными единицами измерения — так называемые составные единицы, например Ньютон для измерения силы (1 Н = 1 кг*м/с2). Разрешение подобного рода соотношений может быть реализовано, если определить два подкласса класса Unit — один для представления простых единиц, PrimeUnit, другой для представления составных, CompoundUnit, и определить две связи, сопоставляющие одной составной единице два
(рис 7.4) Представление составных единиц измеренийВ медицине, где хранение данных измерений имеет особое значение, измерения почти всегда связываются с пациентом, для которого они производились. К тому же, медицинских измерений, имеющих, например, значение длины, очень много. Для того чтобы различать оба этих атрибута измерения — объект измерения и вид измерения (например, пациент Иванов Петр Сергеевич и окружность его талии), — их нужно явно ввести в модель. Так возникает образец измерение. Этот образец становится полезным, если имеется очень много различных измерений для каждого объекта, группируемых в достаточно много видов измеряемых явлений.
(рис 7.5) Набор классов для представления результатов измеренийБывает, однако, необходимо вести учет не только количественных измерений, но и качественных наблюдений, результат которых представляется не числом, а некоторым значением перечислимого типа (группа крови II, ожог 3-й степени и пр.). При этом наблюдения очень похожи на измерения: относятся к некоторому объекту и определяют некоторое значение для какого-то вида наблюдений.
Для совместного представления результатов наблюдений и измерений можно использовать шаблон наблюдение, структура классов которого показана на рис. 7.6. Требуется некоторая привычка, чтобы быстро разложить по этим классам какой-нибудь реальный пример. Например, группа крови — вид явлений, II — явление этого вида, наблюдение заключается в том, что у Петра Сергеевича Иванова была обнаружена именно такая группа крови. Эти усилия, однако, с лихвой окупаются огромным количеством фактов, которые без изменений можно уложить в эту схему.
(рис 7.6) Набор классов для представления результатов как измерений, так и наблюденийРабота по выделению и классификации
| Виды стилей и конкретные стили | Контекст использования и основные решения | Примеры | |
|---|---|---|---|
| Конвейер обработки данных (data flow) | Система выдает четко определенные выходные данные в результате обработки четко определенных входных данных, при этом процесс обработки не зависит от времени, применяется многократно, одинаково к любым данным на входе. Обработка организуется в виде набора (необязательно последовательности) отдельных компонентов-обработчиков, передающих свои результаты на вход другим обработчикам или на выход всей системы. Важными свойствами являются четко определенная структура данных и возможность интеграции с другими системами |
||
| Пакетная обработка (batch |
Один-единственный вывод производится на основе чтения некоторого одного набора данных на входе, промежуточные преобразования организуются в виде последовательности | Сборка программной системы: компиляция, сборка системы, сборка документации, выполнение тестов | |
| Каналы и фильтры (pipe-and-filter) | Нужно обеспечить преобразование непрерывных потоков данных. При этом преобразования инкрементальны и следующее может быть начато до окончания предыдущего. Имеется, возможно, несколько входов и несколько выходов. В дальнейшем возможно добавление дополнительных преобразований |
Утилиты UNIX | |
| Замкнутый цикл управления ( |
Нужно обеспечить обработку постоянно поступающих событий в плохо предсказуемом окружении. Используется общий диспетчер событий, который классифицирует событие и отдает его на асинхронную обработку обработчику событий такого типа, после чего диспетчер снова готов воспринимать события |
Встроенные системы управления в автомобилях, авиации, спутниках. Обработка запросов на сильно загруженных Web-серверах. Обработка действий пользователя в GUI |
|
| Вызов-возврат (call-return) | Порядок выполнения действий четко определен, отдельные компоненты не могут выполнять полезную работу, не получая обращения от других | ||
| Процедурная декомпозиция | Данные неизменны, процедуры работы с ними могут немного меняться, могут возникать новые. Выделяется набор процедур, схема передачи управления между которыми представляет собой дерево с основной процедурой в его корне |
Основная схема построения программ для языков C, Pascal, Ada | |
| Абстрактные типы данных ( |
В системе много данных, структура которых может меняться. Важны возможности внесения изменений и интеграции с другими системами. Выделяется набор абстрактных типов данных, каждый из которых предоставляет набор операций для работы с данными такого типа. Внутреннее представление данных скрывается |
Библиотеки классов и компонентов | |
| Многоуровне-вая система (layers) | Имеется естественное расслоение задач системы на наборы задач, которые можно было бы решать последовательно — сначала задачи первого уровня, затем, используя полученные решения, — второго, и т.д. Важны переносимость и возможность многократного использования отдельных компонентов. Компоненты разделяются на несколько уровней таким образом, что компоненты данного уровня могут использовать для своей работы только соседей или компоненты предыдущего уровня. Могут быть более слабые ограничения, например, компонентам верхних уровней разрешено использовать компоненты всех нижележащих уровней |
Телекоммуникацион-ные протоколы в модели OSI (7 уровней), реальные протоколы сетей передачи данных (обычно 5 уровней или меньше). Системы автоматизации предприятий (уровни интерфейса пользователя–обработки запросов–хранения данных) |
|
| Клиент-сервер | Решаемые задачи естественно распределяются между инициаторами и обработчиками запросов, возможно изменение внешнего представления данных и способов их обработки | Основная модель бизнес-приложений: клиентские приложения, воспринимающие запросы пользователей и сервера, выполняющие эти запросы | |
| Интерактивные системы | Необходимость достаточно быстро реагировать на действия пользователя, изменчивость пользовательского интерфейса | ||
| Данные–представление–обработка (model–view-controller, MVC) | Изменения во внешнем представлении достаточно вероятны, одна и та же информация представляется по-разному в нескольких местах, система должна быстро реагировать на изменения данных. Выделяется набор компонентов, ответственных за хранение данных, компоненты, ответственные за их представления для пользователей, и компоненты, воспринимающие команды, преобразующие данные и обновляющие их представления |
Наиболее часто используется при построении приложений с GUI. Document-View в MFC (Microsoft Foundation Classes) — документ в этой схеме объединяет роли данных и обработчика |
|
| Представление–абстракция–управление (presentation–abstraction–control) | Интерактивная система на основе агентов, имеющих собственные состояния и пользовательский интерфейс, возможно добавление новых агентов. Отличие от предыдущей схемы в том, что для каждого отдельного набора данных его модель, представление и управляющий компонент объединяются в агента, ответственного за всю работу именно с этим набором данных. Агенты взаимодействуют друг с другом только через четко определенную часть интерфейса управляющих компонентов |
||
| Системы на основе хранилища данных | Основные функции системы связаны с хранением, обработкой и представлением больших количеств данных | ||
| Репозиторий ( |
Порядок работы определяется только потоком внешних событий. Выделяется общее хранилище данных — репозиторий. Каждый обработчик запускается в ответ на соответствующее ему событие и как-то преобразует часть данных в репозитории |
Среды разработки и |
|
| Классная доска (blackboard) | Способ решения задачи в целом неизвестен или слишком трудоемок, но известны методы, частично решающие задачу, композиция которых способна выдавать приемлемые результаты, возможно добавление новых потребителей данных или обработчиков. Отдельные обработчики запускаются, только если данные репозитории для их работы подготовлены. Подготовленность данных определяется с помощью некоторой системы шаблонов. Если можно запустить несколько обработчиков, используется система их приоритетов |
||
Многие из представленных стилей носят достаточно общий характер и часто встречаются в разных системах. Кроме того, часто можно обнаружить, что в одной системе используются несколько
Более подробного рассмотрения заслуживают
Название. Каналы и фильтры (pipes and filters).
Назначение. Организация обработки потоков данных в том случае, когда процесс обработки распадается на несколько шагов. Эти шаги могут выполняться отдельными обработчиками, возможно, реализуемыми разными разработчиками или даже организациями. При этом нужно принимать во внимание следующие факторы:
Действующие силы.
Решение. Каждая отдельная задача по обработке данных разбивается на несколько мелких шагов. Выходные данные одного шага являются входными для других. Каждый шаг реализуется специальным компонентом — фильтром (filter). Фильтр потребляет и выдает данные инкрементально, небольшими порциями. Передача данных между фильтрами осуществляется по каналам (pipes).
Структура. Основными ролями компонентов в рамках данного стиля являются фильтр и канал. Иногда выделяют специальные виды фильтров — источник данных (data source) и потребитель данных (data sink), которые, соответственно, только выдают данные или только их потребляют. Каждый поток обработки данных состоит из чередующихся фильтров и каналов, начинается источником данных и заканчивается их потребителем.
Фильтр получает на свой вход данные и обрабатывает их, дополняя их результатами обработки, удаляя какие-то части и трансформируя их в некоторое другое представление. Иногда фильтр сам требует входные данные и выдает выходные по их получении, иногда он, наоборот, может реагировать на события прихода данных на вход и требования данных на выходе. Фильтр обычно потребляет и выдает данные некоторыми порциями.
(рис 7.7) Пример структуры классов для образца каналы и фильтрыКанал обеспечивает передачу данных, их буферизацию и синхронизацию обработки их соседними фильтрами (например, если оба соседних фильтра активны, работают в параллельных процессах). Если никакой дополнительный буферизации и синхронизации не требуется, канал может представлять собой простую передачу данных в виде параметра или результата вызова операции.
На рис. 7.7 показан пример диаграммы классов для данного образца, в котором 3 канала реализованы неявно — через вызовы операций и возвращение результатов, а один — явно. Из участвующих в этом примере фильтров источник и потребитель данных, а также Filter 1 запрашивают входные данные, Filter 3 сам передает их дальше, а Filter 2 и запрашивает, и передает данные самостоятельно.
(рис 7.8) Сценарий работы проталкивающего фильтраДинамика. Возможны три различных сценария работы одного фильтра — проталкивание данных (push model, фильтр сам передает данные следующему компоненту, а получает их только в результате передачи предыдущего), вытягивание данных (pull model, фильтр требует данные у предыдущего компонента, следующий сам должен затребовать данные у него) и смешанный вариант. Часто реализуется только один вид передачи данных для всех фильтров в рамках системы. Кроме того, канал может буферизовать данные и синхронизовать взаимодействующие с ним фильтры. Сценарии работы системы в целом строятся в виде различных комбинаций вариантов работы отдельных фильтров.

(рис 7.10) Сценарий работы вытягивающего фильтра(рис 7.9) Сценарий работы буферизующего и синхронизующего каналаРеализация. Основные шаги реализации следующие:
Могут быть выделены специальные каналы для передачи сообщений об ошибках.
При возникновении ошибок ввода соответствующий фильтр может игнорировать дальнейшие входные данные до получения определенного разделителя, гарантирующего, что после него идут данные, не связанные с предыдущими.
Следствия применения образца.
Достоинства:
Недостатки:
Примеры. Наиболее известный пример использования данного образца — система утилит UNIX [8], пополненная возможностями оболочки (shell) по организации каналов между процессами. Большинство утилит могут играть роль фильтров при обработке текстовых данных, а каналы строятся при помощи соединения стандартного ввода одной программы со стандартным выводом другой.
Другим примером может служить часто используемая архитектура компилятора как последовательности фильтров, обрабатывающих входную программу — лексического анализатора (лексера), синтаксического анализатора (парсера), семантического анализатора, набора оптимизаторов и генератора результирующего кода. Таким способом можно достаточно быстро построить прототипный компилятор для несложного языка. Более производительные компиляторы, нацеленные на промышленное использование, строятся по более сложной схеме, в частности, используя элементы стиля "Репозиторий".
Название. Многоуровневая система (layers).
Назначение. Реализация больших систем, которые имеют большое количество разноплановых элементов, использующих друг друга. Некоторые аспекты работы таких систем могут включать в себя много операций, выполняемых разными компонентами на разных уровнях (т.е. одна задача решается за счет последовательных обращений между элементами разных уровней, другая — тоже, но участвующие в решении этих задач элементы могут быть различны). При этом нужно принимать во внимание следующие факторы:
Действующие силы.
Решение. Выделяется некоторый набор уровней, каждый из которых отвечает за решение своих собственных подзадач. Для этого он использует интерфейс, предоставляемый предыдущим уровнем, предоставляя, в свою очередь, некоторый интерфейс для следующего уровня.
Каждый отдельный уровень может быть в дальнейшем декомпозирован на более мелкие компоненты.
Структура. Основными компонентами являются уровни. Иногда выделяют клиентов, использующих интерфейс самого верхнего уровня. Каждый уровень предоставляет интерфейс для решения определенного множества задач. Сам он решает их, опираясь на интерфейс предшествующего уровня.
На каждом уровне может находиться много более мелких компонентов.
(рис 7.11) Пример структуры многоуровневой системы.Классы для уровней условные, они обычно декомпозируются на наборы более мелких компонентов
Динамика. Сценарии работы системы могут быть получены компоновкой следующих четырех. Часто в виде многих уровней реализуются коммуникационные системы, две такие системы могут взаимодействовать через самый нижний уровень — при этом пара симметричных сценариев (по подъему–спуску обращений) выполняется в рамках одного общего сценария на разных машинах.
(рис 7.12) Составной сценарий пересылки сообщения по сетиРеализация. Основные шаги реализации следующие:
Следствия применения образца.
Достоинства:
Недостатки:
Примеры. Наиболее известный пример использования данного образца — стандартная модель протоколов связи открытых систем (Open System Interconnection, OSI) [9]. Она состоит из 7 уровней:
Модель OSI оказалась все же слишком сложна для использования на практике. Сейчас наиболее широко применяемые наборы протоколов строятся по урезанной схеме OSI — в ней отсутствуют пятый и шестой уровни, прикладные протоколы пользуются непосредственно службами протоколов транспортного уровня.
Другой пример многоуровневой архитектуры — архитектура современных информационных систем или систем автоматизации бизнеса. Она включает следующие уровни [3]:
Чаще всего этот уровень рассматривается как интерфейс пользователя. В его рамках определяется представление данных для передачи другим системам или пользователям, набор экранов, форм и отчетов, с которыми имеют дело пользователи.
На нем находятся все ресурсы, которыми пользуется система, в том числе другие системы. Очень часто используемые ресурсы сводятся к набору баз данных, необходимых для работы организации. На этом уровне определяется структура используемых ресурсов и способы управления ими, в частности, конкретное размещение данных по таблицам реляционной базы данных или классам объектной базы данных и соответствующий набор индексов. Чаще всего схемы баз данных оптимизируются под конкретный набор запросов, и поэтому их структура несколько отличается от концептуальной схемы данных, находящейся на предыдущем уровне.
Часто два средних уровня объединяются в один — уровень функционирования приложений, что дает в результате широко используемую трехзвенную архитектуру информационных систем.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.