Лекция 8 - hydronship

advertisement
Лекция 8
Прямое и обратное проектирование
Прямым проектированием (Forward engineering) называется процесс преобразования модели в код путем отображения на
некоторый язык реализации. Процесс прямого проектирования приводит к потере информации, поскольку напиязыке
санныеUML
на модели семантически богаче любого из существующих объектно-ориентированных языков. Фактичеразличие
и является
основной причиной, по которой, помимо кода, необходимы и модели. Некоторые структурски именно
это
свойства системы, такие как кооперации, или ее поведенческие особенности, например взаимодействия, могут
ные
визуализированы
в UML, но в чистом коде наглядность теряется.
быть легко
Прямое проектирование диаграммы классов производится следующим образом:
1. Идентифицируются правила отображения модели на один или несколько языков программирования по выбору. Это
допустимо делать как при работе над одним конкретным проектом, так и для организации в целом.
2. В зависимости от семантики выбранных языков, часто, приходится отказываться от использования некоторых
возможностей
UML. Например, язык UML допускает множественное наследование, а некоторые языки программирования,
напримр, Smalltalk - только одиночное.
В связи с этим можно или запретить авторам моделей пользоваться множественным наследованием (что сделает
создаваемые модели зависимыми от языка), или разработать идиомы (be about, we are going - собираться) для трансляции таких расширенных возможностей в
конструкции, поддерживаемые данным языком программирования (что усложнит отображение).
3. Следует применять помеченные значения для специфицирования языка программирования. Это можно сделать
как на уровне
индивидуальных классов (если нужна тонкая настройка), так и на более высоком уровне, например для пакетов
коопераций.
или
4. следует пользоватся инструментальными средствами для прямого проектирования моделей.
На рис. 8.4 изображена простая диаграмма классов, на которой проиллюстрирована реализация образца (см. главу 28)
цепочки обязанностей. В данном примере представлены три класса: Client (Клиент), EventHandler (ОбработчикСобытий) и
GUIEventHandler (ОбработчикСобытийГИП). Первые два из них являются абстрактными, а последний - конкретным. Класс
EventHandler содержит обычную для данного образца операцию handleRequest (обработатьЗапрос), хотя в рассматриваемом
случае было добавлено два скрытых атрибута.
Определенное для каждого класса помеченное значение показывает, что они будут преобразованы в код на
языке Java. Прямое проектирование в данном случае легко осуществимо с помощью специального инструмента.
Так, для класса EventHandler будет сгенерирован следующий код (Рис.8.4.1):
public abstract class EventHandler {
EventHandler successor;
private Integer currentEventID;
private String source;
EventHandler () {}
public void handleRequest () {}
}
Рис.8.4.1.
Обратным проектированием (Reverse engineering) называется процесс преобразования в модель кода, записанного на каком-либо языке программирования. В результате этого процесса получается очень большой объем информации, часть которой находится на более низком уровне детализации, чем необходимо для построения полезных
моделей. В то же время обратное проектирование никогда не бывает полным. Восстановить точно исходную модель на основе кода не удастся, если только инструментальные средства не включали в комментариях к исходному тексту информацию, выходящую за пределы семантики языка реализации. Пример, представленный на рис. 3.3,
был создан с помощью обратного проектирования библиотеки классов языка Java.
Обратное проектирование диаграммы классов осуществляется следующим образом:
1. Идентифицируются правила для преобразования из выбранного языка реализации. Это можно сделать на
уровне
проекта или организации в целом. С помощью инструментального средства указывается код, который нужно подвергнуть обратному проектированию.
2. Инструментальное
средство
используется
для
создания
новой
модели
или
для
модификации ранее созданной.
3. На основе инструментального средства, создается диаграмма классов путем опроса полученной модели. Можно
начать, например, с одного или нескольких классов, а затем расширить диаграмму, следуя вдоль некоторых отношений или добавив соседние классы. Раскрываются или скрываются детали содержания диаграммы в зависимости от намерений разработчика.
Рекомендации
Создавая диаграмму классов на языке UML, следует помнить, что это всего лишь графическое изображение
статического вида системы с точки зрения проектирования. Взятая в отрыве от остальных, ни одна диаграмма классов не может и не должна охватывать этот вид целиком. Диаграммы классов описывают его исчерпывающе, но
каждая в отдельности - лишь один из его аспектов.
Хорошо структурированная диаграмма классов обладает следующими свойствами:
•
заостряет внимание только на одном аспекте статического вида системы с точки зрения проектирования;
•
содержит лишь элементы, существенные для понимания данного аспекта;
• показывает детали, соответствующие требуемому уровню абстракции, опуская те, без которых можно
обойтись;
•
сохраняет важные аспекты семантики.
При изображении диаграммы классов руководствуйтесь следующими правилами:
•
диаграмме дается имя, связанное с ее назначением;
•
элементы располагаются так, чтобы свести к минимуму число пересекающихся линий;
•
пространственно элементы организуются так, чтобы семантически близкие сущности располагались ря-
дом;
•
чтобы привлечь внимание к важным особенностям диаграммы, используются примечания и цвет;
•
следует не показывать слишком много разных видов отношений; как правило, в каждой диаграмме
классов должны доминировать отношения какого-либо одного вида.
Часть III. Изучение структурного моделирования Глава 9. Углубленное изучение классов
Классификаторы в UML
Классы - это самые важные строительные блоки объектно-ориентированных систем. Однако Классы являются одной из разновидностей более общих строительных блоков UML- классификаторов. Классификатор - это механизм, описывающий структурные и поведенческие свойства. К числу классификаторов относятся классы, интерфейсы, типы данных, сигналы, компоненты, узлы, прецеденты (варианты использования) и подсистемы.
Классификаторы, и в особенности классы, характеризуются большим количеством дополнительных
свойств, кроме простейших, таких как атрибуты и операции., которые были описаны в предыдущих разделах (см. главу 4). Можно моделировать кратность, видимость, сигнатуры, полиморфизм и другие характеристики. Язык UML позволяет определить семантику класса с расчетом па любой нужный вам уровень
формализации.
В UML существует несколько разновидностей классификаторов и классов;
важно выбрать ту из них, которая позволяет лучше всего моделировать необходимую абстракцию реальности.
Введение
На определенном этапе строительства дома вам надлежит принять решение о том, какие материалы
нужно использовать (см. главу 2). В самом начале достаточно лишь указать, что это будет дерево, камень
или сталь. Такой степени детализации довольно для того, чтобы двигаться дальше. На выбор материалов,
разумеется, будут влиять требования проекта, - например, сталь и бетон подойдут, если дом должен выдерживать натиск ураганов. Впоследствии ваш выбор определит дальнейшее развитие проекта, - скажем, выбрав дерево вместо стали, вы должны будете учитывать, что оно выдерживает меньшую нагрузку.
По мере дальнейшей работы над проектом базовые решения придется уточнить и добавить ряд деталей,
которые позволят конструктору произвести расчеты на прочность, а строителям - приступить к возведению
дома. Например, вы можете выбрать не просто дерево, но дерево определенной твердости или пропитанном
определенным составом, который защищает древесину от насекомых.
Те же самые правила применимы и к созданию программного обеспечения. В самом начале работы над
проектом достаточно сказать, что вы собираетесь использовать класс Клиент, выполняющий определенные
обязанности (см. главу 6). По мере уточнения архитектуры и перехода к конструированию придется определить структуру класса (его атрибуты) и его поведение (операции), необходимые и достаточные для выполнения указанных обязанностей. Наконец, дойдя до стадии преобразования модели в исполняемую систему, вы должны будете смоделировать и такие детали, как, видимость отдельных атрибутов и операций, семантику параллелизма класса в целом и его операций, а также реализуемые классом интерфейсы.
Как видно из рис. 9.1, язык UML позволяет определять большое количество развитых свойств класса. Эта
нотация дает возможность визуализировать, специфицировать, конструировать и документировать класс
на любом желаемом уровне, детализации, достаточном для поддержки прямого и обратного проектирования моделей и кода.
Некоторые сущности в UML не имеют экземпляров (см. главу 13). К их числу относятся, например, пакеты (см. главу 12) и отношения обобщения (см. главы 5 и 10). В общем смысле те элементы моделирования,
которые могут иметь экземпляры, называются классификаторами (ассоциации, рассматриваемые в главах 5
и 10, и сообщения, обсуждаемые в главе 15, также могут иметь экземпляры, но они отличаются от экземпляров классов).
Еще важнее то, что классификаторы характеризуются структурными (в форме атрибутов) и поведенческими
(в форме операций) свойствами. Все экземпляры одного классификатора обладают общим рядом свойств.
Хотя самым важным видом классификатора в UML является класс, который характеризуется описанием совокупности объектов с общими атрибутами, операциями, отношениями и семантикой, помимо классов существуют
и другие классификаторы:
•
•
•
•
•
•
•
интерфейс - набор операций, используемых для того, чтобы специфицировать услуги, предоставляемые классом или компонентом (см. главу 11);
тип данных - тип, значения которого не индивидуализированы; сюда входят примитивные встроенные типы,
такие как числа и строки, а также перечислимые типы, например Boolean (см. главу 4);
сигнал - спецификация асинхронного стимула, используемою для связи между экземплярами (см. главу 20);
компонент - физическая замещаемая часть системы, соответствующая ан цификации набора интерфейсов и
обеспечивающая их реализацию (см. главу 25);
узел - физический элемент, который существует во время выполнения приложения и представляет собой вычислительный ресурс; обычно он обладаеч', как минимум, некоторой памятью, а иногда и способностью к обработке данных (см. главу 26);
прецедент, или вариант использования, - описание совокупности последовательностей действий (в том числе
вариантных), выполняемых системой, которые вызывают наблюдаемое изменение, представляющее интерес
для конкретного актера (см. главу 16);
подсистема - совокупность элементов, из которых отдельные составляют спецификацию поведения других элементов (см. главу 31).
Почти каждый из перечисленных видов классификаторов обладает как структурными, так и поведенческими
свойствами (исключением являются интерфейсы -они могут не иметь атрибутов). Используя любой из них в модели, можно применять все свойства, обеспечивая такой уровень детализации, который необходим для адекватного
описания сути абстракции.
Графические изображения классификаторов представлены на рис. 9.2.
Примечание Придерживаясь минималистского подхода, можно было бы использовать одну и ту же пиктограмму
для всех классификаторов. Однако это неразумно, поскольку, например, классы и компоненты являются принципиально разными абстракциями (первый - логической, а второй - физической), и на
этом основании стоит отвести для них несходные графические образы. С другой стороны, бросаться в
противоположную крайность — использовать различные пиктограммы, для каждого типа классификаторов - также не имеет смысла, поскольку, например, классы и типы данных не слишком различаются между собой. В языке UML найден компромисс: существенно различающиеся классификаторы имеют собственные пиктограммы, а остальные выделяются специальными ключевыми словами
(такими, как type, signal или subsystem,).
Видимость
Одна из деталей, наиболее существенных для атрибутов и операций классификаторов, - их видимость. Видимость свойства говорит о том, может ли оно использоваться другими классификаторами. Естественно, это подразумевает видимость самого классификатора. Один классификатор может «видеть» другой, если тот находится в области действия первого и между ними существует явное или неявное отношение (см. главы 5 и 10). В языке UML
можно определить три уровня видимости:
•
public (открытый) - любой внешний классификатор, который «видит» данный, может пользоваться его открытыми свойствами. Обозначается знаком + (плюс) перед именем атрибута или операции;
•
protected (защищенный) - любой потомок данного классификатора (см. главу 5) может пользоваться его защищенными свойствами. Обозначается знаком # (диез);
private (закрытый) - только данный классификатор может пользоваться закрытыми свойствами. Обозначается
символом -(минус).
•
На рис. 9.3 показаны открытые, защищенные и закрытые атрибуты и методы для класса Toolbar.
Видимость свойств классификатора определяют для того, чтобы скрыть детали его реализации и показать
только те особенности, которые необходимы для осуществления обязанностей, продекларированных абстракцией.
В этом и заключается основная причина сокрытия информации, без чего не обойтись при создании надежной и
гибкой системы. Если символ видимости явно не указан, обычно предполагается, что свойство является открытым. Отношения дружественности (Friendship) позволяют классификатору показывать другим свои закрытые детали (см. главу 10).
Примечание Видимость в UML соответствует общепринятой семантике большинства языков программирования,
таких как C++, Java, Ada и Eiffel
Download