Дж. Рамбо, М. Блаха - UML 2.0 - Объектно-ориентированное моделирование и разработка (1158633), страница 126
Текст из файла (страница 126)
Одним из критериев качества модели классов является отражение ограничений системы в структуре этой модели. Мы указали возможность вычисления объекта ВоипйпВВок, который определяется параметрами геометрической фигуры и не несет дополнительной информации. /ВоопсйпВВок Вгарпгсарггтгичв Ещрае Песгапя!е Рис. 015.1. Усовершенствованная диаграмма классов для ограничивающего прямоугольника 15.9. Выводимая ассоциация на рис. 015.3 обеспечивает прямое прослеживание от Раде (Страница) к Е(пв (Строка). Выводимые сущности ускоряют выполнение некоторых запросов, но требуют дополнительных затрат ресурсов на обновление выводимых данных при изменении исходных данных.
Ассоциация Раде Егпе (Страница Строка) представляет собой композицию ассоциаций Раде Со!итп (Страница Колонка) и Со!итп Егпе (Колонка Строка). /Раде Ьтв Рис. 015.3. Усовершенствованная модель издательской системы 15.13. Ниже приведен набросок решения. В нашем коде отсутствуют утверждения, которые обычно включаются для проверки правильности. В частности, следовало бы включить оператор для обработки ситуации, когда полюс является подклассом, а отношение не является обобщением.
Если код взаимодействует с пользователями или внешними источниками данных, лучше всего включать в него операторы обработки ошибок 532 Ответы к избранным упражнениям в качестве альтернативной ветви при проверке условий, которые «должны» быть истинными. Сгасе1пьег1ТапсеРаСЬ (с1азз1, с1авз2): РаСЬ ( раТЬ := пен Рагь; // поиск пути от с1азв1 как от потомка с1авв2 с1авзх: с1авв1; нЬ11е с1аввх 1в пог пи11 бо абб с1авзх То Ргопг ог раТЬ) с1авзх с1авз2 СЬев геСигп раСЬ| с1аввх : с1авзх.чегзирегс1азв(); // не удалось найти путь от с1авз1 вверх до с1авз2 ищем путь от с1авз2 вверх к с1азз1 рагь.с1еаг()) с1аззх := с1авз2) ньг1е с1авзх 1з поС пи11 бо абб с1аввх Со тгопг от раТЬ! с1аввх с1азв1 Тьеп геТигп раСЬ: с1аввх:= с1аввх.оегзирегс1азз (); // два класса не состоят в непосредственной связи // возвращается пустой путь раТЬ.
с1еаг () ) гегигп раТЬ; С1азв::ЧеТЯирегс1азз (): С1авв ( Рог вась епб 1п зе11.соппесС1оп бо: 1г ТЬе епб гз а ЯиЬс1авз ТЬеп: ге1аг1опвитр : епб ге1аг1опвьтр) 11 ге1аС1опвьгр 1в а Яепега11гаг(оп Сьеп: оТЬегЕпбв := ге1аТгопвитр.епб) Рог еасЬ оСЬегЕпб 1п оТЬегЕпбв бо: 11 огьегЕпб 1в а Яирегс1азз ТЬеп: гегигп оСЬегЕпб.с1авв геСигп пи11; ) 15.16.
На рис. О15.5 показана усовершенствованная модель. Членство в политической партии — это не неотъемлемое свойство избирателя, а изменяемая ассоциация. Новая модель лучше описывает избирателей, не принадлежащих к политическим партиям, и позволяет изменять принадлежность к партиям. Если бы избиратели могли принадлежать сразу к нескольким партиям, мы легко могли бы изменить кратность в своей модели.
В нашем случае партия — это экземпляр класса Ро!(г(са!Рагту, а не подкласс и ее не нужно указывать в модели явным образом. Новые партии могут добавляться в систему без изменения модели вместе с атрибутами для их описания. тетвег Уо(ег гед(з(еюб(п роинсв(рену Рис.
015.$. Усовершенствованная модель с воплощением партий Ответы к избранным упражнениям 533 15.18. Левая модель на рис. 015.6 показывает индекс множества точек, реализованный через ассоциацию с двойным квалификатором. Ассоциация сортируется сначала по квалификатору х, а затем по квалификатору у. Поскольку индексирование — зто оптимизация, модель содержит избыточную информацию, которая уже присутствует в объектах класса Рота роиЫу диайде(( вззосlаноп Бlпд!у г(иаИЯеб аззос)ввел Рис.
016.6. Модели для упорядоченной совокупности точек Правая модель отражает ту же систему, но с одиночными квалификаторами ассоциаций. Мы добавили избыточный класс Яптр (Полоса~, характеризую)ций все точки с заданной координатой х. Правую модель проше реализовать в большинстве систем, поскольку структура данных с единственным ключом сортировки имеется в большинстве библиотек классов. В фактической реализации для представления ассоциации могут использоваться бинарные деревья, связные списки или массивы. Приведенный ниже код определяет методы поиска, добавления и удаления точек. Ро1пгсо11есггоп::зеагсь (геч1оп: яесгапо1е): Бег ог Ро1пг ( создать новое пустое множество точек; сканировать значения х в ассоциации до х > геч1оп.хю1п~ нь11е квалификатор х <- гес)оп.хюах бо: сканировать значения у лля значения х до у >= гед1оп.уюгп; нь11е квалификатор у <= гев1оп.ужах бо: доеавить (х, у) в множество точек; перейти к следующему значению у; перейти к следующему значению х; возвратить множество точек; Ро1пГСо11ессгоп::абб (ро1пс: Ро1пс) ( сканировать значения х в ассоциации до х > рогпс.х) 11 х ро1пс.х съеп сканировать значения у лля значения х до у > рогпс.у) вставить точку в ассоциацию в текущей позиции) Ро1псоо11ессгоп::бе1есе (рогпс: Рогат) ( сканировать значения х в ассоциации до х >= ро1пг.х1 11 х ро1пг.х Гьеп сканировать значения у для значения х до у >= рогпс.у; 534 Ответы к избранным упражнениям гг у рохпс.у сьеп для кавдой точки совокупности с текушими значениями к, у ГГ точка совокупности = роьпс сЬев удалить точку совокупности; сетпсп1 возвратить ошибку «точка не найдена»; ) Обратите внимание, что операцию сканирования нужно реализовать через бинарный поиск, чтобы получить логарифмическое, а не линейное время поиска.
Если значения заканчиваются, операция поиска передает управление следующему оператору. 17.2. Стрелка указывает, что ассоциация реализуется в соответствующем направлении. ° Техт <-> Вох. Пользователь может редактировать текст, а прямоугольник должен изменять свой размер в соответствии с текстом, поэтому необходим указатель от Техг к Вох. Текст может существовать только в прямоугольниках, поэтому предполагается, что пользователь может перетащить прямоугольник, в результате чего текст также должен переместиться. Поэтому необходим указатель от Вох к Тех(.
° Соииесйои <-> Вох. Прямоугольник можно перетащить, и при этом переместятся его соединения, поэтому необходим указатель от Вох к Соииесйои. Можно перетащить связь, н тогда переместятся ее соединения с прямоугольниками, поэтому необходим указатель от Соииесйои к Вох. Очевидного способа упорядочения в данном случае нет. ° Соииесйои <-> Еги1. То же объяснение, что и в предыдущем пункте. ° СоИесг(ои -> огсгеге«1 Вох.
По заданной совокупности мы должны иметь возможность найти входящие в нее прямоугольники. Необходимость прослеживания в обратном направлении, судя по всему, отсутствует. Упорядочение прямоугольников необходимо для отслеживания их расположения на экране (передний план или задний план). ° Со11есгюи -> ои1еге«1 ЕтИ. То же объяснение, что и в предыдущем пункте. 18.6. 1) Мы приводим пример кода на )ана, который реализует двустороннюю ассоциацию между классами А и В типа «один-к-одному» при помощи указателя в каждом классе.
Каждый класс обеспечивает поддержку своего собственного гюлюса ассоциации и обращается к другому классу для обслуживания второго полюса. Каждый класс содержит внутренний атрибут прс)асегпргодгеээ ( выполняетсяОбновление), который позволяет прервать бесконечную рекурсию. Мы приводим только атрибуты и методы, необходимые для реализации ассоциации. Мы приводим код только для одного класса, потому что код во втором классе должен быть точно таким же, за тем исключением, что классы А н В и объекты а и Ь должны быть заменены на В, А и Ь, а соответственно. Таким образом, поле ргйнасе и )э должно стать ргунасе А а, а метод А.
Бесп(п пес«п) станет и. Яесд(А пес«А). Обратите внимание, что мы Ответы к избранным упражнениям 535 до минимума сократили проверку ошибок и опустили возвращение логических переменных или перечислимых типов, а также обработку исключений. Этот код предполагает наиболее жесткий уровень управления доступом. Классы считаются принадлежащими к разным пакетам, а потому могут обращаться только к открытым элементам друг друга. // Зача // класс А с ассоциацией типа один-к-одному с классом В 1шрогг ВРаскаяе. риЬ11с а1авз А ( ргсчаге В Ь пи11) рг1чаге Ьоо1еап ирбаге1пРогягевз = Га1зе> // проверка, есть ли В для А риьттс Ьоо1еап Паев () ( гесигп Ь ! пи11) ) // установка ассоциации А с пенВ риЬ11а чосб зеСВ (В пенВ) ( (пенВ = пи11) гегигп; //не уатанавливаем асаоциацию, нужно вызвать гешочеВ 11 ( ирбасе1пргодгезв) гесигп; //разрываем рекурсию 11 (Ь = пенВ) гегигп) // этот А уже связан с В 11 (пенВ.ьазА()) гегигп; // пенВ должен быть свободен 11 (ПазВ()] гешочеВ()1 // удаление текушей ассоциации, т.к.
допустимо только 1:1 ирбаге1пРговгезв = Сгие! пенВ.зеСА(СПсз): // запрашиваем пенВ об обновлении его полюса Ь = пенВь // обновление ланного полюса ирбаСе1пргочгевв = та1веь // Удаление аааоциации с В // в ассоциации 1."1 аргумент при удалении ие требуетая риЬ1)с чо1б гешочеВ() ( 11 (ПазВ() == га1ве ) геСигп; // нечего удалять 11 ( ирбасе1пРгочгевз) гесигп) // разрываем рекурсию ирбасе1пРгочгезз = сгиес Ь. гешочеА (); запрос на удаление Ь = пи11) // удаление своего полюса ирбасе1пргочгевв = са1веь Достаточно часто классы, ссылающиеся друг на друга в своих интерфейсах, помещаются в один пакет, а потому могут иметь расширенные знания друг о друге.