Дж. Арлоу, А. Нейштадт - UML 2 и Унифицированный процесс - Практический объектно-ориентированный анализ и проектирование (1158625), страница 79
Текст из файла (страница 79)
Посколькуинтерфейсы определяют только контракт, они обеспечивают возможность существования любого количества конкретных реализаций,подчиняющихся этому контракту.432Глава 19. Интерфейсы и компонентыВ следующих разделах мы расскажем о компонентах, а затем обсудим,как можно сочетать компоненты и интерфейсы в CBD.19.8. Что такое компонент?Спецификация UML 2.0 [UML2S] гласит: «Компонент представляет модульную часть системы, которая инкапсулирует ее содержимое, и реализация компонента замещаема в рамках его окружения».
Компонент как черный ящик, внешнее поведение которого полностью определяется его предоставляемыми и требуемыми интерфейсами. Поэтому один компонент может быть заменен другим, поддерживающимтот же протокол.Компонент – модульная и замещаемая часть системы, инкапсулирующаяее содержимое.Компоненты могут иметь атрибуты и операции и участвовать в отношениях ассоциации и обобщения. Компоненты – это структурированные классификаторы. У них может быть внутренняя структура, включающая части и соединители. Структурированные классификаторырассматривались в разделе 18.12.1.
Если вы до сих пор не ознакомились с ними, рекомендуем сделать это сейчас, прежде чем двигатьсядальше.Компоненты могут представлять чтото, экземпляр чего может бытьсоздан во время выполнения, например EJB (Enterprise JavaBean).Или ими может быть представлена абсолютно логическая конструкция, такая как подсистема, экземпляры которой создаются толькокосвенно через создание экземпляров ее частей.Компонент может быть представлен одним или более артефактами.Артефакт представляет некоторую физическую сущность, напримерисходный файл. В частности, компонент EJB мог бы быть представленфайлом JAR (Java Archive – Javaархив).
Более подробно артефактыобсуждаются в разделе 24.5.На диаграмме компонентов могут быть показаны компоненты, зависимости между ними и то, как компонентам назначаются классификаторы. Компонент отображается в виде прямоугольника со стереотипом«component» (компонент) и/или пиктограммой компонента в верхнемправом углу, как на рис. 19.15. У компонентов могут быть предоставляемые и требуемые интерфейсы и порты.Компонент может иметь внутреннюю структуру. Части можно показать вложенными внутрь компонента (рис. 19.16) или находящимисяснаружи и соединенными с ним отношением зависимости. Обе формысинтаксически эквивалентны, хотя первая нотация нам кажется болеенаглядной.43319.8. Что такое компонент?компонентпредоставляемыйинтерфейстребуемыйинтерфейс«component»AI1I2Рис.
19.15. Нотация компонентаЕсли у компонента есть внутренняя структура, как правило, он будетделегировать обязанности, определенные его интерфейсами, своимвнутренним частям. На рис. 19.16 компонент A предоставляет интерфейс I1 и требует интерфейс I2. Он инкапсулирует две части типа b и c.Он делегирует поведение, описанное его предоставляемым и требуемым интерфейсами b и c соответственно.«component»A«delegate»«delegate»b:BI1c:CI1I2I2Рис.
19.16. Внутренняя структура компонентаИнтерфейсы позволяют гибко объединять компоненты.Компоненты могут зависеть от других компонентов. Для разъединениякомпонентов в качестве посредников в зависимости всегда используются интерфейсы. Если компоненту требуется интерфейс, представитьэто можно в виде зависимости между компонентом и интерфейсом либоиспользовать разъем сборки, как показано на рис.
19.17.IParty«component»Party«component»AddressIAddressIAddress«component»MailingListManagerIPostBoxРис. 19.17. Разъем сборки между компонентами434Глава 19. Интерфейсы и компонентыНа рис. 19.17 показано следующее:•Компонент Party предоставляет два интерфейса типа IParty (вечеринка)и IAddress (адрес). Эти интерфейсы отображены в виде кружков.•Компоненту MailingListManager (менеджер рассылки писем) требуются два интерфейса типа IAddress и IPostBox (почтовый ящик). Онипредставлены в виде гнезд.•Между компонентами Party и MailingListManager – разъем сборки. Онпоказывает, что MailingListManager общается с компонентом Party посредством предоставляемого интерфейса IAddress.•В этой модели компонент Party играет роль фасада (см. раздел 19.12.1)для разъединения компонента MailingListManager и деталей компонента Address.Часто компоненты отображаются просто как «черные ящики», к которым прикреплены их предоставляемые и требуемые интерфейсы.
Однако компонент может быть представлен и как «белый ящик» (рис. 19.18).Такое полное представление раскрывает внутренние детали компонента. В нем могут быть показаны любые предоставляемые интерфейсы,требуемые интерфейсы, реализации или ассоциированные артефакты.«component»Party«providedInterfaces»IAddressIPartyпредоставляемыеинтерфейсы«artifacts»party.jarартефакты, которыеобеспечивают физическоепредставление компонентаРис. 19.18. Полное представление компонента19.9. Стереотипы компонентовКомпоненты – вероятно, наиболее богатые стереотипами элементыUML.
Это объясняется тем, что компоненты могут использоваться дляпредставления различных типов сущностей. UML 2 предоставляет небольшой набор стандартных стереотипов компонентов, которые перечислены в табл. 19.2. Один из них, «subsystem», рассматривается болееподробно в следующем разделе.Если при моделировании используются профили UML, они определяют собственные стереотипы компонентов.43519.10. ПодсистемыТаблица 19.2СтереотипСемантика«buildComponent»Компонент, определяющий набор сущностей для организационных или системных целей разработки.«entity»Компонент постоянной информации, представляющийбизнеспонятие.«implementation»Определение компонента, не имеющего собственной спецификации. Он является реализацией отдельного компонента, обозначенного стереотипом «specification», с которымимеет отношение зависимости.«specification»Классификатор, определяющий область объектов без описания физической реализации этих объектов.
Например,компонент, обозначенный стереотипом «specification», имеет только предоставляемые и требуемые интерфейсы и неимеет реализующих классификаторов.«process»Компонент, ориентированный на транзакции.«service»Не имеющий состояния функциональный компонент, вычисляющий значение.«subsystem»Единица иерархической декомпозиции больших систем.19.10. ПодсистемыПодсистема – это компонент, действующий как единица декомпозициибольшой системы.
Подсистемы изображаются как компонент со стереотипом «subsystem».Подсистема – это компонент, действующий как единица декомпозициибольшой системы.Подсистема – это логическая конструкция, используемая для декомпозиции большой системы в управляемые части. Экземпляры самихподсистем не могут создаваться во время выполнения, но могут создаваться экземпляры их содержимого.С точки зрения UP подсистемы являются ключевой концепциейструктурирования. Деление системы на подсистемы позволяет разложить большую, сложную задачу разработки на много меньших и болееуправляемых подзадач. Это ключ к успешной разработке системыс использованием UP.Интерфейсы используются для сокрытия деталей реализации подсистем.Интерфейсы идут рука об руку с подсистемами, как показано нарис.
19.19. В данном примере подсистеме GUI известны только интер436Глава 19. Интерфейсы и компоненты«subsystem»GUICustomerManagerAccountManagerOrderManager«subsystem»BusinessLogicРис. 19.19. Подсистемы и интерфейсыфейсы CustomerManager, AccountManager и OrderManager. Она ничего не знает о внутренней реализации подсистемы BusinessLogic (бизнеслогика).Это значит, что в принципе подсистему BusinessLogic можно было быполностью заменить даже несколькими подсистемами, если вместе онибудут предоставлять такой же набор интерфейсов. Аналогично можнобыло бы заменить подсистему GUI другой подсистемой GUI, требующейтакой же набор интерфейсов.
Такое использование интерфейсов разъединяет подсистемы и обеспечивает гибкость архитектуры.Интерфейсы объединяют подсистемы, создавая архитектуру системы.19.11. Выявление интерфейсовПри проектировании системы или ее части следует проверить проектную модель на предмет выявления некоторых интерфейсов. Это довольно просто сделать, выполнив следующее:• Каждая ассоциация должна быть поставлена под сомнение – длякаждой задается вопрос: «Действительно ли данная ассоциациядолжна быть установлена с конкретным классом объектов или онадолжна быть более гибкой?» Если решено, что ассоциация должнабыть более гибкой, чем она была бы в случае привязки к конкретному классу, необходимо рассмотреть возможность использованияинтерфейса.• Каждое сообщение должно быть поставлено под сомнение – для каждого задается вопрос: «Действительно ли данное сообщение должноотправляться объектам только одного класса или оно должно бытьболее гибким?» Если оно должно быть более универсальным (т.
е.если можно найти классы, которые могли бы отправлять такие же19.12. Проектирование с использованием интерфейсов••••••437сообщения объектам других классов), необходимо рассмотреть возможность использования интерфейса.Выделить группы операций, которые могут повторно использоваться гделибо еще. Например, если многим классам системы необходима возможность работы с некоторым устройством вывода, следует подумать о проектировании интерфейса Print.Выделить наборы операций, повторяющиеся в нескольких классах.Выделить наборы атрибутов, повторяющиеся в нескольких классах.Провести поиск классов, играющих в системе одинаковую роль –роль может указывать на возможный интерфейс.Рассмотреть возможности будущего расширения системы.
Иногдадаже после небольшого предварительного анализа можно спроектировать легко расширяемые в будущем системы. Ключевой вопрос: «Понадобится ли добавлять к системе какиелибо классыв будущем?» Если ответ положительный, необходимо попытатьсяопределить один или более интерфейсов, которые будут описыватьпротокол добавления этих новых классов.Рассмотреть зависимости между компонентами – везде, где это возможно, в них должны быть введены разъемы сборки в качестве посредников.Как видите, существует много возможностей для использования интерфейсов. Подробности проектирования с применением интерфейсоврассматриваются в следующем разделе.19.12.
Проектирование с использованиеминтерфейсовПри проектировании весьма полезно, если сущности ведут себя максимально одинаково. Применяя интерфейсы, можно проектировать общие протоколы, которые могли бы реализовываться многими классами или компонентами. Хороший пример этому – система, которую мыразработали, чтобы предоставить общий интерфейс для несколькихунаследованных систем.
Проблема состояла в том, что у каждой системы был свой протокол связи. Нам удалось скрыть эту сложность заединственным интерфейсом, состоящим из операций open(...), read(...),write(...) и close().Приведем другой пример. Рассмотрим систему, моделирующую организацию (например, систему управления человеческими ресурсами).В ней много классов сущностей, имеющих имя и адрес, например Person,OrganizationalUnit, Job.