М. Фаулер, К. Скотт - UML. Основы - 2002 (1158629), страница 32
Текст из файла (страница 32)
В данном случае мне не нужно, чтобы все ассоциации были двунаправленными. Я связал пациента с некоторой совокупностью наблюдений, поскольку сами наблюдения используются только в контексте отдельных пациентов. роЫ1с с)азз ОЬзегча11оп ех1епбз Ооаа1ПОЬ(ез1 ( рсЫ1с Осзегча11оп (Рпепоаепоп ге1ечап1РПепоаепоп, Ра11еп1 ра11еп1, Оате чпепОЬзегчеб) ( рпепоаепоп = ге)ечап1 Рпепоаепоп; ра11еп1. оЬзе гча11опзАбб(1Ыз ); чпепцозегчеб = чпепОЬзегчеб; рг1ча1е РПепоаепоп рпепоеепоп; рг1чате Оа1е чпепсозегчеб; ) роЫ1с с)азз Ра11еп1 ех1епбз Ооаа1ПОЬ)ес1 ( роЫ1с Ра11еп1(81г1пц папе) ( зпрег(папе); чо(б оозегча11опзАбб(ОЬзегча11оп печцоз) ( 162 Глава11.
Язык ()М( и программирование оозе гча11опз. або Е)еаеп1( печОЬз); рг1чаге Чесгог оовегча11опз = пев Чес1ог(); ) С помощью следующего фрагмента кода я могу создавать наблюдения. пей Ра11еп1("Абаев"), регз1з1(): печ Оозегча11оп(рпеповепопТурв. Ое1("Овпбег"), рпвпоавпопйааеб("аа)е"), Ра11еп1.9е1("Абаев"), печ ваге (96, 3, 1) ); с)азз РпепоаепопТуре ( рсЫ1с Рпеповепоп рпеповепопйааеб(81г1ЬО паве) ( Епсаега11оп е = рЬеповепа(); ЧЫ)в (е.пазйогеЕ)вввпгз() ) ( РЬепоавпоп еасп = (Рпепоаепоп)в.пех1Е)ваеп1(); 11 (еасп.паве().ецса1в(паве)) ге1сго васЬ; ): ге1огп пс11; После создания наблюдений необходимо иметь возможность поиска самого последнего показателя.
с)азз Ра11вп1 рсЫ1с РЬеповепоп рпепоаепопОГ (РпепоавпопТуре рЬепоаепопТуре) ( ге1огп ()а1ез10озегча11оп(рпвпоаепопТуре) == псм ? печ йс11рпепоаепоп(): 1а1ез10озегча11оп(рпеповепопТуре).рпеповепоп() ); ) рг1ча1е Оозег1а11оп )агез10Ьзегча11оп(рпеповепспТуре ча)се) ( гегс гп 1а1ез10Ьзе гча11оп)п(оЬве гча11опзОГ(ча)се) ); ) рг1чаге Епсаега11оп оозегча11спзОГ(РЬепоавпспТуре ча)ое) ( Чес1ог гевс11 = пей Чес1ог(); Епцавга11оп в оозегча11опз(); ЧЫ)е (е. ЬазйогеЕ)еаепгв() ) ( ОЬзегча11оп еасп = (Оозегча11оп) е,пвх1Е)еаеп1(); 11 (еасЬ.рпепоаепопТуре() = = ча)ое) гезс11. аббЕ)еаеп1(васо); ): 163 Переход к кодированию ге1ого гезс11. е1еаеп1з(): ) рг1чазе ОЬзегча11оп 1азез1ОЬзегча11оп1п (Епсаега11оп оЬзегча11опЕпса) ( 1Г ((оозегча11опЕпов.
ПазйогеЕ1еаеп1з() ) гезсгп пс11; ОЬзвгча11оп гвзс11 = ОЬзвгча11оп)оЬзегча11опЕпса,пвх1Е1еаеп1(); 1Г (!оозегча11опЕпсв.пазйогеЕ)евепзз() ) гезсгп гезс11; со ( ОЬзегча11оп васП = (ОЬзегчв11оп)оЬзегча11опЕпса. пех1Е1евеп1(); 1Т (васо.впепОЬзегчео(). а11ег(гезс11.впепОЬзегчео() ) ) гезс11 еасп; ) вп11е (оЬзегча11спЕпса. ПазйогеЕ1евепзз() ); ге1сгп гезс11; ) с1азз ОЬзегча1!оп рсЫ1с РпвповепспТуре РПепсаепопТуре() ( ге1сгп рпвповепоп.рпеповепопТуре(), ) Для реализации зтого можно объединить нескольких методов в один. Для иллюстрации можно было бы построить диаграмму, но я не буду етого делать. Способ, которым я декомпозирую метод, больше относится к реорганизации (см.
главу 2), чем к уже выполненному проектированию. Теперь можно рассмотреть добавление поведения для измерений. Во-первых, давайте посмотрим на определение класса Измерение (Меавигешеп1) и его конструктор. роЫ1с с)азз Иеазогеввпз ех1епоз ОЬзегча11оп ( роЫ1с Иеазсгваеп1(0сап111у авосп1, РпепоаепопТуре рпепоаепопТуре, Ра11еп1 ра11еп1, Оа1е апепзьзегчео) ( 1п111а11хе (ра11еп1, апепОьзвгчес); ааооп1 = авооп1; рпеповепопТуре рпеповепопТуре; рсЫ1с РпепоаепопТуре рпепоавпопТуре() ( ге1сгп рпеповепопТуре; 164 Гпава11. Язык ()М(.
и программирование рср)1с 81г1пр 1о81г1пэ() ( гегсгп рпеповепоптурв + ": " + авоспгв; ): рг1ча1е Осап111у авооп1; рг1ча1е РоеповепопТуре рэеповвпопТуре; ) с1авв ОЬвегча11оп рго1ес1ео чо1О 1п111а111е(Ра11еп1 ра11еп1, Оа1в чоепОЬвегчео) ( ра11еп1. оьвегча11опвАОО(1п(в); воепОЬвегчео = впепОЬвегчео, ) Следует заметить, что диаграмма классов служит хорошей отправной точкой для разработки данного фрагмента кода.
И снова нам требуется самое последнее измерение. С1авв Ра11еп1 рср)1с Осап111у 1а1ев1Авооп101(роеповепопТуре ча1се) ( гв1сгп ((1а1ев1веавогввеп1(ча1ов) == пс11) ) 1 печ Мс110сап111у();1а1ев1веаыгевеп1(ча1се), авосп1(); рг1ча1е Меавсгевеп1 1агев1Меавсгевеп1(РПеповепопТуре ча1се) ( 11 (Хагев10ьвегча11оп(ча1ов) == пс11) гв1огп псП; 1( (!1агев10овегча11оп(ча1се).1ввеавсгевеп1() ) гвгсгп пс11; ге1сгп (Меаыгевепг)1агев10Ьвегча11оп(ча1се); ) В каждом их этих случаев диаграмма классов определяет основную структуру, мы же только добавляем поведение, чтобы реализовать интересующие нас запросы, На данной стадии можно описать наше положение с помощью диаграммы классов уровня спецификации, изображенной на рис. 11.7.
Посмотрим, каким образом данная диаграмма акцентирует внимание на интерфейсе, а не на реализации. Роль от Типа Показателя к Показателю моделируется как некая квалифицированная роль, поскольку это главный интерфейс класса Тип Показателя. Аналогично показана связь Наблюдения с Типом Показателя, поскольку и здесь существует интерфейс, хотя имеется только одно измерение с прямым указателем на Показатель. Глядя на эту диаграмму, мы можем сделать вывод, что единственное различие между классами Измерение и Наблюдение заключается в том, 165 Переход к кодированию Рис, 11.7.Другая модель спецификации наблюдения пациенпга что Измерение обладает количеством. Класс Измерение можно совсем удалить из модели спецификации, предположив, что любое наблюдение обладает количеством (которое может иметь неопределенное значение пи)1).
Мы могли бы все же оставить отдельный класс Измерение с полями величина и тип показателя, но при этом никто за пределами данного пакета не будет знать о существовании данного класса. Чтобы обеспечить создание соответствующего класса, нам может понадобиться добавить методы образца «Фабрика» (Гас1огу) 1Гамма и др., 1995 [20)) либо в класс Наблюдение, либо в класс Пациент.
Я оставлю это дополнение в качестве упражнения для читателей и перейду к автоматическому связыванию Показателя с Измерением. Этот общий процесс изображен на рис. 11.7. 166 Глава 11. Язык 0МЕ и программирование Сначала необходимо добавить метод вызова в конструктор класса Измерение. С1азз Веазогеввп1 роЫ1с Неавсгевепг (Осапг11у авоспг, РПеповвпопТуре РЬеповепопТурв, Ра11епг ра11впп Оагв впепсозегчез) 1п111а11ге (ра11епг, впвпсозегчеа); авоспг = авоопг; рЬеповепопТуре рЬеповепопТурв; рЬеповепоп са1сс1агвРЬеповепопрог( авоспг); Далее эта задача делегируется классу Тип Показателя. С1азз Веазсгевепг роЫ1с РЬеповепоп са1со1агвРЬеповепопрог(соап11(у агц) ( гегогп рпеповепопТуре.рпеповепоп1пс1оз1пц(агц); ) Далее по очереди запрашивается каждый показатель.
С)азз РпеповепопТуре рсЫ1с РЬеповепоп рпеповвпоп1пс1оа1пц (Осап11гу агц) ( Епсвегаг1оп е = рЬеповапа(); вП11в (е. ПазйогеЕ)евепгз() ) ( РЬеповепоп васЬ = (Рпеповепоп) е.пехгЕ1евепг(); 17 (еасЬ.1пс1освз(агц)) гегогп вась; ): гегсгп пс11; ) С1азз РПеповепоп роЫ1с Ьоо1еап 1пс1сзез (Осап111у агц) ( гегсгп ( гапце == пс)1 7 Га1зе: гапце.1пс1осез (агц)); ) Данный код достаточно явно следует из диаграммы последовательности. На практике я обычно пользуюсь диаграммой последовательности, чтобы только приближенно представить взаимодействие, а затем по мере кодирования вношу в него необходимые изменения. Если взаимодействие имеет существенное значение, я поддерживаю диаграмму последовательности в активном состоянии как часть моей документации. Если же я сочту, что диаграмма последовательности не вносит никакой дополнительной ясности в программный код, то сдам ее в архив.
Этот небольшой пример показывает, как использовать языка ПМ) в совокупности с языком программирования, однако при этом он дает и общее представление о процессе. Нет необходимости черезчур формально подходить к выполнению проекта и пытаться использовать аб- Переход к кодированию 167 солютно все возможности языка УМ1.. Вполне достаточно пользоваться только теми из них, которые представляются вам полезными. Схематическое представление проекта с помощью диаграммы классов и диаграммы взаимодействия помогает привести мысли в порядок и существенно облегчает процесс кодирования. Я рассматриваю эти схемы в качестве первых прототипов.
В дальнейшем эти диаграммы вовсе не обязательно поддерживать, однако может оказаться, что они будут облегчать понимание программного кода вам самим и другим разработчикам, Нет необходимости использовать какое-то изысканное и дорогостоящее САЯЕ-средство. Обычной доски и несложного графического редактора на компьютере может оказаться вполне достаточно. Конечно, существуют полезные САЯЕ-средства, и если вы участвуете в крупномасштабном проекте, то следует рассмотреть возможность применения какого-либо из них. Если вы решите использовать какое-либо САЯЕ-средство, сравните его возможности с простым графическим редактором и текстовым процессором.