Модель в целом может обладать (или не обладать) важными свойствами, которые оказывают значительное влияние на ее практическую применимость. Исчерпывающим образом описать эти свойства во вступительном обзоре невозможно ‒ их детализация рассредоточена по все книге, но назвать их необходимо в самом начале.
Прежде всего, модель должна удовлетворять формальным требованиям к описанию сущностей, отношений и их комбинаций. Другими словами, модель должна быть синтаксически правильной. Например, отношение (ребро в графе модели) всегда определяется между сущностями, оно не может просто так "висеть в воздухе". На диаграмме линия должна начинаться и заканчиваться в фигуре, иначе это синтаксическая ошибка. Некоторые тексты в модели (например, описания атрибутов и операций классов) должны иметь определенный синтаксис.
В UML первична семантика, а синтаксис вторичен. Конечно, стандарт рекомендует вполне определенный синтаксис, но это не более чем рекомендация: разработчики инструментов вправе использовать другой синтаксис, и этим правом они пользуются. Таким образом, понятие синтаксической правильности, столь ясное для традиционных языков программирования, для UML становится несколько расплывчатым.
Большинство инструментов, особенно новых, просто не позволяют ввести в модель синтаксически неправильную конструкцию.
В некоторых случаях даже синтаксически правильная модель может содержать такие конструкции, семантика которых не определена или неоднозначна. Такая модель называется противоречивой, а модель, в которой все в порядке и семантика всех конструкций определяется однозначно, называется непротиворечивой. Например, пусть мы определим в модели, что класс A является подклассом класса B, класс B ‒ подкласс C, класс C ‒ подкласс D, а класс D ‒ подкласс A. Каждое из этих отношений обобщения в отдельности допустимо и синтаксически правильно, а все вместе они противоречивы.
Далее в тексте мы всегда указываем правила непротиворечивости при обсуждении соответствующих конструкций языка. Впрочем, их не так много и по большей части они совершенно очевидны на уровне здравого смысла: синтаксические конструкции нужно использовать так, чтобы не возникало двусмысленностей при семантической интерпретации.
Инструменты стараются проверять выполнение правил непротиворечивости, как могут, но 100% уверенности не обеспечивают. Другими словами: пользуясь любым инструментом, можно составить синтаксически правильную и семантически бессмысленную модель. Ответственность за непротиворечивость модели лежит на ее авторе.
Модель не создается мгновенно ‒ она появляется в результате многочисленных итераций (рис. Процесс моделирования) и на каждой из них "по определению" не полна. Инструмент обязан дать возможность сохранить модель в любом (синтаксически правильном) состоянии с тем, чтобы в дальнейшем ее можно было дополнять и изменять.
Что такое полная модель? На этот вопрос нельзя ответить однозначно. В некоторых случаях оказывается достаточно одной диаграммы использования (например, концептуальная модель), а в других необходимы диаграммы всех типов, прорисованные до мельчайших деталей (например, модель реализации). Все зависит от прагматики, т.е. от того, для чего составляется модель. Если модель составляется с расчетом на автоматическую генерацию кода, то полной естественно считать такую модель, по которой инструмент может сгенерировать работающую программу. За редким исключением пока это практически невозможно. Если модель составляется с целью спецификации требований к разрабатываемому приложению, то модель можно считать полной, если заказчик и разработчик согласны считать ее таковой. Критерий, как видите, субъективный.
Мы склонны считать, что понятие полноты модели следует определять применительно к конкретному процессу разработки (см. главу 5). Грубо говоря, для каждой фазы процесса разработки есть свое понятие полноты: полная модель фазы анализа, полная модель фазы проектирования и т.д.
Последняя тема, рассматриваемая в этой главе, является в некотором смысле уникальной особенностью UML. В описании метамодели (семантики UML) определено достаточно большое количество точек вариации семантики (semantic variation point). По сути, авторы стандарта, описывая семантику какого-то понятия, говорят: "мы понимаем это так-то и так-то, но допускаем, что другие могут это понимать иначе". При реализации языка в конкретном инструменте разработчики в точке вариации семантики вправе выбрать альтернативный вариант, если он не противоречит семантике остальной части языка.
Точки вариации семантики расставлены в глубинных слоях языка, там, где приходится принимать во внимание особенности реализации инструмента и конкретную систему программирования. Рядовому пользователю точки вариации семантики не заметны и он может о них не думать. Например, в UML каждый конкретный объект является экземпляром одного конкретного класса (статическая типизация). Но это точка вариации семантики: можно допустить динамическую типизацию, при которой объект во время своей жизни может менять класс, которому он принадлежит.
Эта замечательная особенность придает языку необходимую гибкость и универсальность: ведь UML предназначен для моделирования в разных средах с разной операционной семантикой. Жесткая фиксация одного единственного решения связала бы разработчиков инструментов по рукам и ногам, стандарт вступил бы в конфликт с требованиями реальной жизни (такие конфликты всегда заканчиваются гибелью стандарта). Авторы языка приняли нетрадиционное и мудрое компромиссное решение: они допустили свободу, но под контролем ‒ все точки вариации семантики явно отмечены в метамодели, в других местах никаких вольностей не допускается.
Таким образом, UML ‒ это графический язык моделирования общего назначения, имеющий нотацию, семантику и прагматику, регулируемую международными стандартами.
UML позволяет строить описательные модели систем, в том числе программных систем, любой сложности.
Модель системы может быть визуализирована в форме графических диаграмм, показывающих сущности моделируемой системы и связи между ними.
В случае необходимости элементы UML могут быть расширены и переопределены средствами самого языка.