Открытая коллекция знаний

OpenU.Ru

Справочник UML. Объектно-ориентированное проектирование.

interface (интерфейс)

Именованное множество операций, описывающих поведение элемента.
См. classifier; realization.

Семантика

Интерфейс - это дескириптор для видимых операций класса, компонента или другой сущности, не определяющий внутреннюю структуру (включая обобщающие блоки, например пакеты). Зачастую интерфейс описывает только небольшую часть поведения класса. Класс, в свою очередь, может поддерживать несколько интерфейсов, причем как независимых, так и пересекающихся между собой. У интерфейсов нет ни реализации, ни атрибутов, ни состояний, ни ассоциаций. У них есть только операции и получаемые сигналы. Интерфейсы могут быть связаны отношениями обобщения. Интерфейс-потомок включает в себя все операции и сигналы своих предков и может добавлять к ним свои собственные. В целом, интерфейс соответствует абстрактному классу, у которого нет ни атрибутов, ни методов, а есть только абстрактные операции. Все операции интерфейса имеют открытую видимость (включать в интерфейс операции с другой видимостью было бы бессмысленно, так как у него нет никакой внутренней структуры, где они могли бы использоваться). Назначение интерфейса можно определить следующим образом.

  • Интерфейс - это множество операций, которые используются для определения услуг класса или компонента.
  • Интерфейс служит для именования такого множества операций, а также для определения их сигнатур и результирующих действий. Главное внимание при этом уделяется не структуре данной услуги, а именно ее результирующему действию. Интерфейс не предлагает реализацию своих операций, в список которых можно также включать сигналы, которые будут обрабатываться классом.
  • Интерфейс используется для определения услуги, которую один элемент поставляет, а другие могут затребовать. Он предоставляет имя множеству операций, которые имеют осуществляют некоторое интересное, с логической тонки зрения, поведение системы или ее части.
  • Интерфейс служит для определения услуги, которую предлагает класс или компонент и которою он реализует. Таким образом, интерфейс охватывает логические и физические границы системы. Логическую реализацию интерфейса может осуществлять как один класс, так и несколько различных классов (которые, скорее всего, будут частью подсистемы какого-то компонента). При этом один или несколько компонентов могут входить в физический пакет, соответствующий интерфейсу.
  • Если интерфейс реализуется (в программном коде) с помощью класса, то этот класс должен объявить или унаследовать все операции интерфейса. Кроме этого, у него также могут иметься дополнительные операции (см. realization). Если же класс реализует не один, а несколько интерфейсов, то и в этом случае он должен иметь все операции, представленные в этих интерфейсах. Одна и та же операция может появляться в различных интерфейсах. Если их сигнатуры совпадают, то они либо представляют собой одну и ту же операцию, либо создают конфликтную ситуацию, и тогда модель считается плохо согласованной. (При реализации могут применяться дополнительные правила для сопоставляемых сигнатур. Например, в языке C++ игнорируются имена параметров и возвращаемых значений.) В интерфейсе нет никаких указаний относительно атрибутов или ассоциаций класса, так как они являются частью его реализации.
  • Интерфейс - это обобщаемый элемент. Интерфейс-прямой потомок наследует все операции своего прямого предка и может добавлять к ним новые. Реализацию можно рассматривать как наследование поведения; класс наследует операции другого классификатора, но не его структуру. Класс может реализовывать другой класс. Класс, служащий для спецификации, ведет себя при этом как интерфейс, так как только его операции затрагивают отношение.
  • Интерфейс может принимать участие в ассоциациях. Однако у него не может быть ассоциации, которая допускала бы навигацию от интерфейса. Интерфейс может участвовать в ассоциации только в том случае, если ассоциация допускает навигацию только, но направлению к интерфейсу.

Нотация

Интерфейс является классификатором, поэтому его можно изображать в виде прямоугольника с ключевым словом "interface". Список операций, поддерживаемых этим интерфейсом, помещается в раздел для операций. Сюда же можно включать и сигналы, у которых есть стереотип "signal". В противном случае их можно разместить в их собственном разделе. Раздел атрибутов вообще не указывается, так как он всегда пустует.
Интерфейс также изображается в виде маленького кружка, под которым указывается его имя. Непрерывная линия может соединять ЭТОТ кружок с классом (или другим элементом), который его поддерживает. Кружок может крепиться к контейнерам более высокого уровня, например пакетам, в которых хранятся классы. Это указываем на то, что класс предоставляет все операции для данного типа интерфейсов (а возможно, и другие). В интерфейсе-кружке невозможно указать список операций, которые он поддерживает, поэтому, если вам нужно, чтобы этот список присутствовал на диаграмме, используйте нотацию в виде прямоугольника. Класс, которому требуются или который использует операции интерфейса, можно соединить с кружком при помощи пунктирной стрелки, наконечник которой указывает на интерфейс. Наличие такой стрелки указывает на то, что классу требуются операции, определяемые в данном интерфейсе, однако это не означает, что ему нужны все они.
Отношение реализации изображается в виде пунктирной линии с треугольным наконечником ("пунктирный символ обобщения"), идущей от класса к интерфейсу, который он поддерживает. Точно такая же нотация используется при изображении реализации типа с помощью класса реализации, В действительности, этот символ можно использовать между двумя любыми символами классификаторов. Это будет указывать на то, что клиент (находящийся у хвоста стрелки) поддерживает все операции, определенные в поставщике (находящемся у наконечника стрелки). При этом структура данных (атрибуты и ассоциации) не поддерживаются.

Рис. 110.

Пример

На рис. 111 изображено упрощенное представление финансовых компонентов, которые имеют отношение к стоимости ценных бумаг. FinanciaLPlanner (ФинансовыйПланировщик) представляет собой программное приложение, которое отслеживает инвестиции, а к персональные затраты. Для работы ему необходима возможность обновлять цены на ценные бумаги. MutualFundAnatyzer (АнализаторВзаимныхФондов) занимается подробным анализом взаимных фондов Для работы ему необходима возможность обновлять цены на основные цепные бумаги, а также цены на фонды. Возможность обновлять цены на ценные бумаги есть у интерфейса UpdatePrices (ОбновитъЦены). Этот интерфейс реализуется двумя компонентами, которые крепятся к символу интерфейса непрерывными линиями' Компонент ManualPriceEntry (ВводЦенВручную) дает пользователю возможность вручную вводить цены на ценные бумаги. Другой компонент, QuoteQuery (ЗапросКотировки), получает данные о ценах на бумаги со специального сервера, с помощью модема или через Интернет.

Рис. 111. Интерфейс, его поставщики и клиенты
На рис. 112 изображена полная нотация интерфейса - в виде символа класса с ключевым словом. В данном случае мы видим, что у этого интерфейса есть две операции: запрос цен на бумаги и получение значения, а также предоставление списка ценных бумаг и получение списка изменившихся цен. На этой диаграмме компонент QuoteQuery связан с интерфейсом при помощи стрелки реализации. Тем не менее, на этой диаграмме изображено то же самое отношение, что и на предыдущей - только с более явной нотацией.
На этой диаграмме вы также видите - новый интерфейс, PeriodicUpdatеPriсеs (ПериодическоеОбновлениеЦен), который является прямым потомком исходного интерфейса. От предка он унаследовал две операции и добавил к ним третью, которая должна осуществлять запрос на периодическое проведение обновления цен. Этот интерфейс реализуется компонентом QuoteServer (СерверКотировок), который является услугой по подписке. Данный компонент реализует те же две операции, что и компонент QuoteQuery, однако делает это по-другому.
В нашем примере он не разделяет реализацию компонента Quote-Query и поэтому не наследуется от него.

Рис. 112. Полная нотация интерфейса
На рис. 112 вы видите разницу между наследованием интерфейса и полным наследованием. Полное наследование включает в себя и наследование интерфейса, однако, реализация интерфейса-потомка может отличаться от реализации предка. Компонент QuoteServer поддерживает интерфейс, реализованный компонентом QuoteQuery, а именно интерфейс UpdatePrices. Однако в этом случае наследования реализации компонента QuoteQuery не происходит. Впрочем, обычно удобно наследовать и программную реализацию, и интерфейс, так что две эти иерархии часто совпадают.
Интерфейс может иметь список сигналов, которые он обрабатывает (рис. 113). Назначение интерфейса - определись поведение классов и компонентой, не ограничивая при этом способы их реализации. Это позволяет разделить наследование интерфейса (как объявлено в языке Java) от наследования реализации.

Рис. 113. Интерфейс и сигналы

Алфавитный указатель