Дж. Рамбо, М. Блаха - UML 2.0 - Объектно-ориентированное моделирование и разработка (1158633), страница 67
Текст из файла (страница 67)
Например, память для строки может выделяться с возвращением указателя на фактическую строку, ш зак 699 290 Глава 1а ° Проектирование системы возвращением копии строки или возвращением указателя с доступом только иа чтение. Стратегии сборки мусора тоже могут быть разными: пометка и подметание (шаг)г апг) зтеер), счетчик ссылок (ге(егепсе соцпйпй), сборка мусора приложением (последиий вариант применяется в С++). ° Коллизии имен. Названия классов, открытые атрибуты и методы принадлежат глобальному пространству имен, поэтому вам остается только надеяться иа то, что коллизий между разными библиотеками ие произойдет.
Большинство библиотек классов используют префиксы, сокращающие вероятность коллизий. 14.3.2. Каркасы Каркас (ггашетог)г — Цоппзоп-881 ) — это скелет программы, детализация которого позволяет создать полноценное приложение. Детализация чаще всего сводится к конкретизации абстрактных классов поведением, специфичным для данного приложения. С каркасом может поставляться библиотека классов, благодаря иаличию которой пользователь может конкретизировать абстрактные классы, выбирая подходящие подклассы из библиотеки, а ие программируя их поведение с нуля.
Каркас состоит ие только из классов, ои включает парадигму потока управления и общие инварианты. Обычно каркасы создаются для целой категории приложений, а библиотеки классов для иих еше более специализироваииы и ие подходят для решения общих задач. 14.3.3. Образцы Образец (рассегп) — это апробированное решение общей задачи. Разные образцы предназначены для различных стадий цикла разработки программного обеспечения. Существуют образцы для анализа, архитектуры, проектирования и реализации. Лучше использовать существующие образцы, чем заново изобретать решения с нуля. Образцы обычно сопровождаются рекомендациями по их использованию, а также характеристиками для сравнения. Использование образцов дает множество преимушеств. Одно из иих состоит в том, что образец разрабатывался другими людьми и успешно применялся ими иа практике.
Следовательно, ои с большей вероятностью окажется корректным и устойчивым, чем ие прошедшее тестирование собственное решение. Кроме того, работая с образцами, вы учите язык, знакомый многим другим разработчикам. Огромное количество книг описывают образцы, тонкости и нюансы работы с ними. Вы можете рассматривать образцы как расширения языка моделирования. Не обязательно мыслить в терминах примитивов, можно оперировать их комбинациями. Образцы — это фрагменты модели, выражающие знания экспертов.
Образец отличается от каркаса. Первый обычно состоит из небольшого количества классов, связанных отношениями. Напротив, каркас обычно содержит иа порядок больше классов и охватывает целую подсистему или даже приложение. Пример с банкоматом. Концепция транзакции подразумевает некоторую возможность повторного использования, потому что транзакции часто встречаются ИА. Разбиение системы на подсистемы 291 в компьютерных системах, и существуют коммерческие программы, обеспечивающие их поддержку.
Кроме того, повторное использование возможно в рамках инфраструктуры, обеспечивающей взаимодействие консорциума с банкоматами и компьютерами банков. 14.4. Разбиение системы на подсистемы Для всех приложений, за исключением самых простых, первый этап проектирования системы сводится к делению этой системы на части. Каждая крупная часть системы называется подсистемой. Каждая подсистема обладает чем-то таким, что отличает ее от других подсистем, например единой функциональностью, физическим размещением или выполнением на однотипном оборудовании. Например, компьютер космического корабля может состоять из подсистем жизнеобеспечения, навигации, управления двигателями и проведения космических экспериментов.
Подсистема (зцЬзузгет) — это не объект и не функция, а совокупность классов, ассоциаций, операций, событий и ограничений, связанных между собой и имеющих хорошо определенный и (желательно) не слишком обширный интерфейс с другими системами. Подсистема обычно определяется сервисами, которые она предоставляет. Сервис (зегч1се) — это группа родственных функций, имеющих общее назначение, например обработка ввода-вывода, построение рисунков и выполнение арифметических операций. Подсистема выражает некоторый цельный взгляд на одну часть задачи.
Например, файловая система является подсистемой операционной системы. Она состоит из набора связанных абстракций, которые практически не зависят от абстракций в других подсистемах (таких как управление памятью и процессами). Каждая подсистема связана с оставшейся частью системы хорошо определенным интерфейсом. Интерфейс определяет форму всех взаимодействий и потоки информации через границы подсистемы, но он не ограничивает внутреннюю реализацию подсистемы. Благодаря этому каждая подсистема может разрабатываться независимо от остальных.
Подсистемы следует определять таким образом, чтобы взаимодействия в системе в целом носили главным образом внутренний характер, то есть осуществлялись внутри подсистем. Это сократит зависимости между разными подсистемами. Количество подсистем не должно быть большим: в качестве разумного ограничения можно взять число 20. Каждая подсистема, в свою очередь, может быть разбита на подсистемы более низкого уровня. Отношения между двумя подсистемами могут быть организованы по принципу клиент-сервер, или же эти подсистемы могут быть одноранговыми.
В первом случае (отношение клиент-сервер) клиент вызывает сервер, который выполняет некоторый сервис и возвращает результат. Клиент должен знать интерфейс сервера, но серверу не обязательно знать интерфейсы клиента, поскольку инициатором взаимодействия всегда является клиент. В одноранговых отношениях каждая подсистема может обратиться к любой другой. Взаимодействие подсистем не обязательно сопровождается немедленным ответом. Одноранговые взаимодействия сложнее, поскольку подсистемы должны 292 Глава И ~ Проектирование системы знать интерфейсы всех остальных подсистем. В них могут возникать циклы, трудные для понимания и проектирования.
Старайтесь разбивать систему на клиентские и серверные части всегда, когда это возможно, потому что одностороннее взаимодействие гораздо проще проектировать, понимать и изменять, чем лвустороннее. Разбиение системы на подсистемы может быть организовано в виде последовательности горизонтальных уровней или вертикальных отделов. 14.4.1. Уровни Многоуровневая система (1ауегео зузсет) — это упорядоченное множество виртуальных миров (ярусов), каждый из которых строится в терминах миров, находящихся ниже него, и образует базис для реализации вышестоящих уровней.
Обьекты каждого уровня могут быть независимыми, но часто между объектами разных уровней наблюдается некоторое соответствие. Знание в данном случае является односторонним: подсистема знает о нижних уровнях, но не о верхних. Между верхними и нижними уровнями существует отношение клиент-сервер. Например, в интерактивной графической системе окна строятся при помощи операций с экраном, которые состоят из операций с отдельными пикселами, которые сводятся к операциям ввода-вывода с устройствами. Каждый уровень может иметь свой набор классов и операций.
Каждый уровень реализуется в терминах классов и операций нижележащих уровней. Многоуровневая архитектура бывает двух видов: открытая и закрытая. В закрытой архитектуре каждый уровень строится только в терминах того уровня, который находится непосредственно под ним. Это сокращает зависимости между уровнями и облегчает внесение изменений, поскольку интерфейс уровня влияет только на следующий за ним уровень.
В открытой архитектуре уровень может использовать функции любого нижележащего уровня. Это сокращает потребность в переопределении операций на каждом уровне, благодаря чему код может получиться более эффективным и компактным. Однако открытая архитектура не способствует сокрытию информации. Изменения в подсистеме могут повлиять на любую вышестоящую подсистему, поэтому такая архитектура получается менее устойчивой, чем закрытая. Оба типа полезны.
Проектировщику приходится взвешивать достоинства и недостатки каждой из них. Обычно в постановке задачи определяются только верхний и нижний уровни. Верхний уровень — это требуемая система, а нижний — зто доступные ресурсы (оборудование, операционная система, существующие библиотеки). Если разница между ними слишком велика (а так бывает достаточно часто), вам приходится вводить дополнительные уровни для сокра1цения концептуальных разрывов между соседними уровнями. Многоуровневую систему можно перенести на другое оборудование, переписав только один из ее уровней.