На этом шаге рассмотрим связи между интерфейсами в UML.
Подобно классу, интерфейс может участвовать в связях обобщения, ассоциации и зависимости, а кроме того, в связи реализации. Реализация – это семантическая связь между двумя классификаторами, один из которых описывает контракт, а другой обязуется его исполнять.
Интерфейс специфицирует контракт для класса или компонента, не навязывая его реализации. Класс или компонент может реализовывать множество интерфейсов – в таком случае он обязуется исполнять все контракты точно и в полной мере, то есть предоставлять набор методов, которые правильно реализуют операции, определенные во всех этих интерфейсах. Набор предлагаемых сервисов называется предоставляемым интерфейсом.
Аналогичным образом класс или компонент может зависеть от множества интерфейсов. При этом он ожидает, что контракты будут предоставлены некоторым набором компонентов, реализующих интерфейсы. Набор сервисов, которые данный класс требует от других классов, называется требуемым интерфейсом. Интерфейс представляет собой соединительный элемент, связывающий компоненты системы. Интерфейс специфицирует контракт, две стороны которого – клиент и поставщик – могут изменяться независимо до тех пор, пока каждый из них соблюдает свои договорные обязанности.
Как явствует из рис. 1, вы можете двумя способами показать, что элемент реализует интерфейс.
Рис.1. Пример реализации
Во-первых, существует простая форма: интерфейс и его связь реализации изображаются в виде линии, соединяющей прямоугольник (класс) и маленький кружок (в случае использования предоставляемого интерфейса) или маленький полукруг (в случае использования требуемого интерфейса). Эта форма удобна и даже предпочтительна, когда вы просто хотите показать соединения в вашей системе. Однако ограничения данной нотации в том, что вы не можете визуализировать операции или сигналы, представленные интерфейсом.
Во-вторых, можно использовать расширенную форму: интерфейс изображается в виде класса со стереотипом, что позволяет визуализировать операции и другие свойства, а также нарисовать связь реализации (для предоставляемого интерфейса) или зависимости (для требуемого интерфейса) от классификатора или компонента к интерфейсу. В UML связь реализации изображается пунктирной линией с большой треугольной стрелкой на конце, указывающей на интерфейс. Эта нотация – нечто среднее между обобщением и зависимостью.
Интерфейсы похожи на абстрактные классы. В частности, ни те, ни другие не могут иметь непосредственных экземпляров. Абстрактный класс, однако, может реализовывать свои конкретные операции. Интерфейс больше напоминает абстрактный класс, у которого абстрактны и все операции.
Первое, что вы видите при работе с интерфейсом, – это набор операций, специфицирующих сервис класса или компонента. Если посмотреть немного глубже, можно выявить полные сигнатуры этих операций наряду с их особыми свойствами, такими как видимость, контекст и семантика параллелизма.
Эти свойства важны, но для сложных интерфейсов их недостаточно, чтобы прояснить семантику предоставляемого ими сервиса и дать понять, как правильно использовать операции. При отсутствии любых других сведений вы должны погрузиться в некую абстракцию, которая реализует интерфейс, чтобы понять, что именно делает каждая операция и как все они должны работать вместе. Однако это лишает смысла использование интерфейса, назначение которого состоит в том, чтобы представлять четкое разделение аспектов в системе.
В модели UML можно указать значительно больше информации, чтобы сделать интерфейс понимаемым и доступным. Во-первых, вы можете сопроводить каждую операцию пред- и постусловиями, а класс или компонент в целом – инвариантами. В результате клиент, желающий использовать интерфейс, сможет понять, что он делает и как его применять, не погружаясь в детали реализации. Если важны формальности, стоит прибегнуть к OCL для спецификации семантики. Во-вторых, можно сопроводить интерфейс конечным автоматом для описания допустимой частичной упорядоченности его операций. В-третьих, сопроводив интерфейс кооперациями, вы определяете его ожидаемое поведение с помощью ряда диаграмм взаимодействия.
На следующем шаге рассмотрим типичные приемы моделирования соединений в системе.