Русский
Русский
English
Статистика
Реклама

Uml design

UML для самых маленьких диаграмма классов

21.07.2020 02:06:53 | Автор: admin


Аве, Кодер! Диаграмма классов UML иллюстрирует структуру системы, описывая классы, их атрибуты, методы и отношения между объектами.

Даже самые малые детки знают, что UML происходит от Unified Modeling Language, если по русски, то унифицированный язык моделирования, который, как гласит легенда, разработали, когда серьезные дяди и тети в конец задолбались плавать в разнообразии кружочков, черточек и облачков.

Для тех, кому лень читать:



Главное действующее лицо



Для начала напомним себе что такое класс? Если в двух словах, то класс представляет собой шаблон для создания объектов,
обеспечивающий начальные значения состояний: инициализацию полей-переменных и реализацию поведения полей и методов.

По сути, класс описывает то, каким объект может быть.

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

Имя класса пишется в самом верхнем делении, затем идут атрибуты класса, типы которых записываются после двоеточия и, наконец, в нижнем делении идут методы.
Тип, который может возвращать метод, записывается после двоеточия в самом конце сигнатуры метода. Модификаторы области видимости изображены перед атрибутами класса и методами.


Каждый параметр в методе может также иметь описание направленности метода: in, out, inout.
На этой иллюстрации, method1 использует p1, как входной параметр и значение p1, каким-то образом, используется методом, а метод не изменяет p1.
Method2 принимает p2, как параметр ввода/вывода, значение p2, каким-то образом, используется методом и принимает выходное значение метода, но сам метод также может изменять p2.
Method3 использует p3, как выходной параметр, иными словами, параметр служит хранилищем для выходного значение метода.

Перспективы диаграммы классов в жизненном цикле разработки программного обеспечения


Мы можем использовать диаграммы классов на разных этапах жизненного цикла разработки программного обеспечения и, как правило, постепенно моделируя диаграммы классов с трех разных точек зрения по мере нашего продвижения по уровням детализации.


Концептуальная перспектива это когда диаграммы интерпретируются как описание вещей в реальном мире. Таким образом, если мы берем концептуальную перспективу, мы рисуем диаграмму, которая представляет концепции в изучаемой области. Эти концепции относятся к классам, которые их реализуют. Концептуальная перспектива считается независимой от языка.


Спецификационная перспектива это когда диаграммы интерпретируются, как описание абстракций программного обеспечения или компонентов со спецификациями и интерфейсами, но без привязки к конкретной реализации.


Имплементационная перспектива это когда диаграммы интерпретируются, как описание реализаций программного обеспечения на определенной технологии и языке.
Таким образом, если ты берешь имплементационную перспективу, ты смотришь на реализацию программного обеспечения.

Типы отношений


Далее, я приведу шесть основных типов обозначений отношений между классами, которые встречаются в UML схемах чаще всего.

Ассоциация.

Аналогично связям, соединяющим объекты, ассоциации соединяют классы. Для того, чтобы между объектами была связь, между ними должна быть ассоциация.
Если предположить, что у нас есть два класса, которые взаимодействуют друг с другом, между ними должна быть проведена непрерывная соединительная линия, обозначающая на схеме ассоциацию. Часто мы также можем увидеть глагол, передающий ее смысл.

Помимо этого, мы также можем указать кратность, то есть число объектов, которые могут принимать участие в отношениях. Кратность задается в виде разделенного запятыми списка интервалов, в котором каждый интервал представлен в виде минимум-максимум.

Например, один студент может учиться у множества преподавателей.
Но и преподаватель может учить множество студентов.

Наследование

Или иногда его еще называют генерализация.
Как следует из названия, это схематическое изображение отношения между родительским классом и его наследниками. Полая стрелка всегда направлена к классу родитель.
Классический пример наследования: классы квадрат, прямоугольник и круг, которые являются наследниками родительского класса фигура.
Мы вправе изображать наследование как отдельно для каждого класса, так и объединять их.
Если наследование происходит от абстрактного класса, то имя такого родительского класса записывается курсивом.

Реализация

Обычно, под этим подразумевается отношение интерфейса и объектов, реализующих этот интерфейс.
Например, интерфейс Owner имеет методы для покупки и продажи частной собственности, а отношения классов Person и Corporation, реализующих этот интерфейс, на диаграмме будут обозначаться в виде пунктирной линии со стрелкой по направлению к интерфейсу.

Зависимость

Объект одного класса может использовать объект другого класса в своем методе.
Если объект не хранится в поле класса, то такой вид межклассовых отношений моделируется как зависимость.
Зависимость, по сути, является специальным случаем ассоциации двух классов, в этом случае, изменения в одном классе неумолимо повлекут за собой изменения в другом.
Например, у класса Person есть метод hasRead с входным параметром book, который возвращает true, если, к примеру, человек прочитал книгу.
Зависимость обозначается пунктирной линией со стрелкой, обращенной к классу, от которого зависят, например, методы другого класса.

Агрегация

Особый тип отношений между классами, когда один класс является частью другого.

Например, рабочее место программиста состоит из стула, стола, компьютера и вентилятора, но при удалении класса рабочее место, у нас просто останутся все эти классы, только по отдельности.
Агрегация показана в виде непрерывной линии с полым ромбом направленным от классов, являющимися частью какого-либо класса к классу-агрегатору.

Композиция

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

Финалочка


UML бывает очень полезен для новичков, находящихся на этапе понимания что к чему долждно идти и от чего наследоваться. Как говорят наши англоязычные коллеги: он помогает увидеть как выглядит весь лес за стволами деревьев.

Поэтому, перед началом твоего, пусть и небольшого, но сногсшибательного проекта, не хватайся сразу за код. Создай сперва архитектуру своего приложения в UML.

Аве!
Подробнее..

Что находится между идеей и кодом? Обзор 14 диаграмм UML

29.06.2020 12:20:00 | Автор: admin


Аве Кодер!

Тебе пришла крутая идея продукта, но ты не хочешь увязнуть в коде и потерять целостную картинку из-за мелких деталей? Ты вот-вот присядешь за то, что крякнул корпоративный сервер и тебе нужно набить что-то крутое и айтишное?
Этот цикл статей будет посвящен полезному, но порой ускользающему от молодой поросли знанию диаграммам UML. И начну я его с обзора существующих диаграмм, поговорим немного об истории и зачем диаграмм должно быть так много.


UML это сокращение от Unified Modeling Language, и, как мы знаем, он является стандартизированным языком моделирования, состоящим из интегрированного набора диаграмм, разработанных, чтобы помочь разработчикам систем и программного обеспечения в определении, визуализации, конструировании и документировании артефактов программных систем, а также, к примеру, для бизнес-моделирования.

UML представляет собой набор лучших инженерных практик, которые доказали свою эффективность в моделировании больших и сложных систем и является очень важной частью разработки объектно-ориентированного программного обеспечения.
UML использует в основном графические обозначения, чтобы выразить дизайн программных проектов. Использование UML помогает проектным группам общаться, изучать потенциальные проекты и проверять архитектурный дизайн программного обеспечения.

Происхождение UML
Цель UML предоставить стандартную нотацию, которая может использоваться всеми объектно-ориентированными методами, а также выбрать и интегрировать лучшие элементы нотаций-предшественников. UML был разработан для широкого спектра приложений. Следовательно, он предоставляет конструкции для широкого спектра систем и видов деятельности (например, распределенных систем, анализа, проектирования и развертывания систем).

UML не возник на пустом месте, ему предшествовали несколько значимых событий, личностей и методологий. Например:
  • Техника объектного моделирования OMT [James Rumbaugh 1991], которая была лучшей для анализа информационных систем с большим объемом данных.
  • Booch [Grady Booch 1994] отлично подходит для разработки и реализации. Грэди Буч много работал с языком Ада и был крупным игроком в разработке объектно-ориентированных методов для языка. Хотя метод Буча был сильным, нотация была воспринята менее хорошо, например, в его моделях преобладали формы облаков, что выглядело не очень аккуратно.
  • OOSE (объектно-ориентированная программная инженерия [Ivar Jacobson 1992]) модель, известная как модель прецедентов это мощная методология для понимания поведения всей системы, область, где ООП традиционно была слабой.

В 1994 году Джим Рамбо, не путать с Джоном Рэмбо, хотя Джим тоже был крут, потому что был, на секундочку, создателем вышеупомянутой техники объектного моделирования, ошеломил мир программного обеспечения, когда он покинул General Electric и присоединился к Грэди Бучу в Rational Corp. Цель партнерства состояла в том, чтобы объединить их идеи в единый унифицированный метод (рабочее название для метода действительно было Единый метод).

К 1995 году создатель OOSE, Ивар Якобсон, также присоединился к Rational, и его идеи (в частности, концепция прецедентов) были включены в новый унифицированный метод, который теперь называется Unified Modeling Language.
В противовес всем известной Банде Четырех, Команда Румбо, Буча и Якобсона известна как Три Амигоса.

На UML также повлияли другие объектно-ориентированные нотации:
  • Меллор и Шлаер [1998]
  • Coad и Yourdon [1995]
  • Вирфс-Брок [1990]
  • Мартин и Оделл [1992]


UML также включает в себя новые концепции, которых в то время не было в других основных методах, таких как механизмы расширения и язык ограничений.

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

Основные цели дизайна UML:
  • Предоставить пользователям готовый, выразительный язык визуального моделирования, чтобы они могли разрабатывать и обмениваться осмысленными моделями.
  • Обеспечить механизмы расширяемости и специализации для расширения основных понятий.
  • Быть независимым от конкретных языков программирования и процессов разработки.
  • Обеспечить формальную основу для понимания языка моделирования.
  • Поощрять рост рынка объектно-ориентированных инструментов.
  • Поддержка высокоуровневых концепций разработки, таких как совместная работа, структуры, шаблоны и компоненты.
  • Интегрировать лучшие практики.


Диаграммы UML подразделяют на два типа это структурные диаграммы и диаграммы поведения.



Структурные диаграммы показывают статическую структуру системы и ее частей на разных уровнях абстракции и реализации, а также их взаимосвязь. Элементы в структурной диаграмме представляют значимые понятия системы и могут включать в себя абстрактные, реальные концепции и концепции реализации. Существует семь типов структурных диаграмм:

  • Диаграмма составной структуры
  • Диаграмма развертывания
  • Диаграмма пакетов
  • Диаграмма профилей
  • Диаграмма классов
  • Диаграмма объектов
  • Диаграмма компонентов


Диаграммы поведения показывают динамическое поведение объектов в системе, которое можно описать, как серию изменений в системе с течением времени. А к диаграммам поведения относятся:

  • Диаграмма деятельности
  • Диаграмма прецедентов
  • Диаграмма состояний
  • Диаграмма последовательности
  • Диаграмма коммуникаций
  • Диаграмма обзора взаимодействия
  • Временная диаграмма


Теперь пару слов о каждой из них

Диаграмма классов

Диаграмма классов это центральная методика моделирования, которая используется практически во всех объектно-ориентированных методах. Эта диаграмма описывает типы объектов в системе и различные виды статических отношений, которые существуют между ними.

Три наиболее важных типа отношений в диаграммах классов (на самом деле их больше), это:

Ассоциация, которая представляет отношения между экземплярами типов, к примеру, человек работает на компанию, у компании есть несколько офисов.
Наследование, которое имеет непосредственное соответствие наследованию в Объектно-Ориентированном дизайне.
Агрегация, которая представляет из себя форму композиции объектов в объектно-ориентированном дизайне.



Диаграмма компонентов

На языке унифицированного моделирования диаграмма компонентов показывает, как компоненты соединяются вместе для формирования более крупных компонентов или программных систем.
Она иллюстрирует архитектуры компонентов программного обеспечения и зависимости между ними.
Эти программные компоненты включают в себя компоненты времени выполнения, исполняемые компоненты, а также компоненты исходного кода.



Диаграмма развертывания

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



Диаграмма объектов

Статическая диаграмма объектов является экземпляром диаграммы класса; она показывает снимок подробного состояния системы в определенный момент времени. Разница в том, что диаграмма классов представляет собой абстрактную модель, состоящую из классов и их отношений.
Тем не менее, диаграмма объекта представляет собой экземпляр в конкретный момент, который имеет конкретный характер.Использование диаграмм объектов довольно ограничено, а именно чтобы показать примеры структуры данных.



Диаграмма пакетов

Диаграмма пакетов это структурная схема UML, которая показывает пакеты и зависимости между ними.
Она позволяет отображать различные виды системы, например, легко смоделировать многоуровневое приложение.



Диаграмма составной структуры

Диаграмма составной структуры аналогична диаграмме классов и является своего рода диаграммой компонентов, используемой в основном при моделировании системы на микроуровне, но она изображает отдельные части вместо целых классов. Это тип статической структурной диаграммы, которая показывает внутреннюю структуру класса и взаимодействия, которые эта структура делает возможными.

Эта диаграмма может включать внутренние части, порты, через которые части взаимодействуют друг с другом или через которые экземпляры класса взаимодействуют с частями и с внешним миром, и соединители между частями или портами. Составная структура это набор взаимосвязанных элементов, которые взаимодействуют во время выполнения для достижения какой-либо цели. Каждый элемент имеет определенную роль в сотрудничестве.



Диаграмма профилей

Диаграмма профилей позволяет нам создавать специфичные для домена и платформы стереотипы и определять отношения между ними. Мы можем создавать стереотипы, рисуя формы стереотипов и связывая их с композицией или обобщением через интерфейс, ориентированный на ресурсы. Мы также можем определять и визуализировать значения стереотипов.



Диаграмма прецедентов

Диаграмма прецедентов описывает функциональные требования системы с точки зрения прецедентов. По сути дела, это модель предполагаемой функциональности системы (прецедентов) и ее среды (актеров).
Прецеденты позволяют связать то, что нам нужно от системы с тем, как система удовлетворяет эти потребности.



Диаграмма деятельности

Диаграммы деятельности представляют собой графическое представление рабочих процессов поэтапных действий и действий с поддержкой выбора, итерации и параллелизма.
Они описывают поток управления целевой системой, такой как исследование сложных бизнес-правил и операций, а также описание прецедентов и бизнес-процессов.
В UML диаграммы деятельности предназначены для моделирования как вычислительных, так и организационных процессов.



Диаграмма состояний

Диаграмма состояний это тип диаграммы, используемый в UML для описания поведения систем, который основан на концепции диаграмм состояний Дэвида Харела. Диаграммы состояний отображают разрешенные состояния и переходы, а также события, которые влияют на эти переходы. Она помогает визуализировать весь жизненный цикл объектов и, таким образом, помогает лучше понять системы, основанные на состоянии.



Диаграмма последовательности

Диаграмма последовательности моделирует взаимодействие объектов на основе временной последовательности. Она показывает, как одни объекты взаимодействуют с другими в конкретном прецеденте.



Диаграмма Коммуникации

Как и диаграмма последовательности, диаграмма коммуникации также используется для моделирования динамического поведения прецедента. Если сравнивать с Диаграммой последовательности, Диаграмма коммуникации больше сфокусирована на показе взаимодействия объектов, а не временной последовательности. На самом деле, диаграмма коммуникации и диаграмма последовательности семантически эквивалентны и могут перетекать одна в другую.



Диаграмма обзора взаимодействия

Диаграмма обзора взаимодействий фокусируется на обзоре потока управления взаимодействиями. Это вариант Диаграммы деятельности, где узлами являются взаимодействия или события взаимодействия. Диаграмма обзора взаимодействий описывает взаимодействия, в которых сообщения и линии жизни скрыты. Мы можем связать реальные диаграммы и добиться высокой степени навигации между диаграммами внутри диаграммы обзора взаимодействия.



Временная диаграмма

Временная диаграмма показывает поведение объекта (ов) в данный период времени. По сути это особая форма диаграммы последовательности и различия между ними состоят в том, что оси меняются местами так, что время увеличивается слева направо, а линии жизни отображаются в отдельных отсеках, расположенных вертикально.




Зачем в UML столько диаграмм?

Причина этого заключается в том, что можно взглянуть на систему с разных точек зрения ведь в разработке программного обеспечения будут участвовать многие заинтересованные стороны, такие как: аналитики, конструкторы, кодеры, тестеры, контроль качества, клиенты, технические авторы.



Все эти люди заинтересованы в различных аспектах системы, и каждый из них требует разного уровня детализации.
Например, кодер должен понимать проект системы и уметь преобразовывать проект в код низкого уровня.
Напротив, технический писатель интересуется поведением системы в целом и должен понимать, как функционирует продукт.
UML пытается предоставить язык настолько выразительным образом, что все заинтересованные стороны могут извлечь выгоду, как минимум из одной диаграммы UML.

Для тех, кому лень читать: youtu.be/0I9aIP5gKCg

Аве!
Подробнее..

Перевод Как построить четкие модели классов и получить реальные преимущества от UML. Часть 4

01.03.2021 12:17:20 | Автор: admin

В первых трех частях(первая, вторая, третья) мы поговорили о UML в целом, семантике и преимуществах хорошей модели.

Настало время обсудить ещё и плохую модель, а также её ключевые отличия от хорошей

Плохая модель классов

Пришло время посмотреть на тип модели классов UML, который можно встретить во множестве проектов. А ещё, увы, который часто поощряется в книгах по UML.

Плохая модельПлохая модельХорошая модель

Понадобится нам для сравнения с плохой моделью

Хорошая модельХорошая модель

Здесь у нас та же самая область применения, но совершенно другая модель. Вот что сразу видно:

  1. Меньше классов и отношений

  2. Более короткие и неполные названия связей

  3. Нет ссылочных атрибутов или тегов идентификаторов

  4. Менее точные (ориентированные на реализацию) типы данных по атрибутам

Более того, если посмотреть на эти 4 элемента суммарно, будет заметно, что некоторых правил приложения вообще нет, а те, что есть, неправильно сформулированы. Пока поговорим о поверхностных отличиях.

Меньше элементов модели

В плохой модели меньше классов, так как роли диспетчеров дежурный и выходной не моделируются. Что сводит на ноль смысл значения поля Время регистрации в системе для каждого диспетчера, который выходной. Это вводит определенную логику если то(для обработки пустых значения, чего не требовалось в хорошей модели) в действия и/или диаграммы состояний.

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

Само собой, у нас тут принцип Чем меньше тем лучше. Но лишь до тех пор, пока это не начинает работать за счет выражения правил. Ведь моделирование в целом процесс аналитический, разбирающий вещи на составляющие. А разработка и реализация это, наоборот, синтез. Разработки моделей, который выполняет объектно-ориентированный анализ, старается выявить и раскрыть все правила приложения. При этом используя столько компонентов, сколько для этого нужно.

Программист (или компилятор) модели сопоставляет элементы анализа и переупаковывает их по мере необходимости, чтобы получить на выходе эффективный код на нужной платформе. При этом такая переупаковка должна учитывать каждое моделируемое правило, хоть никто и не запрещает уменьшать общее количество элементов в процессе. Так что разработка это своего рода умная упаковка.

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

Наша же с вами цель разделить процессы разработки и моделирования, чтобы получить максимальные преимущества от обоих.

Более короткие имена

Плохая модель использует для обозначения связей общий стиль именования ролей. Когда вы создаете диаграмму классов как прямое представление реализации своего кода, роли хороши, тут спору нет. Но для целей анализа куда как эффективнее глагольные фразы.

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

Так как имя роли часто совпадает с именем связанного класса, их можно смело удалять, это не уменьшит выразительность модели. Авиадиспетчер и контролер это одно и то же? ОК, так и запишем.

На самом деле, в случае с плохой моделью нам сложно сказать наверняка, имеем мы в виду, что зона управления назначается диспетчеру постоянно (как место на парковке или стол в опенспейсе), или же мы обсуждаем именно текущий момент. Обратите внимание в хорошей модели пара глагольных фраз управляет трафиком внутри / содержит трафик, управляемый как раз и проясняют возможную путаницу, дополняя объяснение, что же на самом деле значит управлять.

Когда аналитик помещает точную глагольную фразу с обеих сторон каждой связи, он вынужден тщательно рассматривать мощность связи и обусловленность с каждой стороны. Это критично именно здесь выражены многие правила. Следует избегать общих, всеохватывающих глагольных фраз, таких как содержит, является группой, имеет и мое любимое связано с. Просто погуглите композиция и агрегация, чтобы понять, насколько легкомысленно использовать общие термины для выражения точных ассоциаций. Какое утверждение скажет вам больше? Блок памяти разбит на взаимоисключающие части |..* Область или блок памяти является (выберите один вариант агрегация / композиция) из области?

Если вы говорите, что диспетчер управляет трафиком внутри <некоторого числа> зон управления, это вынуждает вас подробно рассматривать правила приложения. Вы наверняка уже поняли, что это 0..* и что нулевой случай соответствует выходному диспетчеру. Если перефразировать все в качестве класса дежурный контролер управляет трафиком внутри <некоторого числа> зон управления, то у вас получится отразить множественность 1..* и закрепить важное правило. Перевернув глагольную фразу с активного залога на пассивный, вы получите контрольную зону, в которой содержится трафик, управляемый только одним дежурнымконтроллером. Он должен всегда быть, плюс должен быть на дежурстве в соответствии с правилами приложения. Глагольные фразы ведут модель к повышенной точности.

Зачем вообще со всем этим заморачиваться, если фразы не переведены в код? На самом деле, они могут появляться как сокращенные имена или как комментарии. Но компилятор модели недостаточно умен, чтобы понять текст в глагольной фразе и выбрать в соответствии с ним тот или иной тип разработки. Наверное, это тоже хорошо. Но всё равно ведь именно множественность и определяет выбор структуры данных и реализацию доступа.

Но как вы пришли к правильному множеству? Модели, у которых общие ассоциативные имена, почти всегда опровергают настоящую природу ассоциации и скрывают интересные граничные условия, которые и приводят к неправильной множественности, порождающей неправильный код.

Отсутствие тегов идентификаторов или ссылочных атрибутов

В наших примерах выше теги не играют какой-то роли, поэтому подробно на них останавливаться я не буду. Ссылочные атрибуты нужны лишь для того, чтобы показать, что данные на самом деле связаны в табличной форме. Современные компиляторы моделей предполагают существование ссылочных атрибутов и могут управлять ими в фоновом режиме. Тем не менее, существует ряд простых методов, с помощью которых можно распространять и объединять ссылочные атрибуты в рамках нескольких отношений, дабы выразить строгие атрибуты. Я так часто поступаю, поэтому сохраняю ссылочные атрибуты по умолчанию.

Предположим, что каждый экземпляр класса уникален. Автоматически. То есть код сгенерируется так, что каждая строка таблицы соответствует однозначно выбираемой сущности. Поэтому нам не нужно накладывать атрибут{I}на каждый класс. Получается, что если у вас есть какой-то класс под названием Thing, то вы можете дать ему искусственный атрибутThing.ID {I}, но это необязательно это верно только для искусственных идентификаторов.

Однако, все ограничения уникальности реального мира должны быть выражены всегда. Представьте, что вы моделируете взлетно-посадочные полосы с одинаковым курсом и стороной в нескольких аэропортах. У вас не может быть две ВПП с одинаковым курсом и стороной (скажем, два 28R). Это ограничение, и его надо выразить.

Как вы это сделаете?

Вот модель, позволяющая это сделать, если включить ссылочный атрибут в качестве компонента идентификатора.

Включение ссылочных атрибутов в идентификатор для выражения ограничения реального мираВключение ссылочных атрибутов в идентификатор для выражения ограничения реального мира

При помощи тегов{I} и {R}в классе взлетно-посадочной полосы эта модель сообщает нам, что уникальный экземпляр ВПП можно выбрать с помощью подставления заголовка, стороны и кода аэропорта. 28L в SFO, например, это взлетно-посадочная полоса 28 слева в Международном аэропорту Сан-Франциско. Так у вас появляется возможность объединять идентификационные данные и ссылочные теги, чтобы выразить тот или иной факт о реальном мире. А именно несколько взлетно-посадочных полос могут иметь один и тот же курс и сторону, но не в одном аэропорту.

Менее точные типы данных

В хорошей модели мы видели строго определенные типы данных приложения. Плохая же полагается на нечетко определенные типы реализации. Давайте на примере атрибутаControlZone.Name. В хорошей модели он определялся как типCZoneID. На рисунке видно, что имена зон управления состоят изCZи целочисленного значения, например,CZ1,CZ2и прочее в таком духе. Возможно, это получится реализовать и при помощи нечетко определенных типов строк. А если мы в модели говорим, что нам нужна строка, что мы просим в реализации? Если программист (или компилятор) модели работает с более специфичным типом приложения, то сможет при необходимости выбрать более жесткий тип реализации.

Вернемся к модели одного класса. У нас есть тип данных под названиемВысота, это можно определить как количество метров в диапазоне 70 000..-400 с точностью, скажем, 0,01. В отношении данного применения это было бы более точным. Конечно же, программист может захотеть реализовать это в виде данных типа float в C или любого другого типа, который соответствует нужной платформе.

Тут всё сводится к тому же принципу модель должна выражать истинные требования области применения. В максимально сжатом и точном объеме. Без ограничений в плане выбора метода написания кода. Ваша цель сделать модель такой, чтобы она выражала реальные условия области применения максимально сжатым образом. Это пригодится, чтобы расширить реальное применение с учетом возможных будущих требований. Допустим, сегодня модель используют только для самолетов с неподвижным крылом. А завтра захотят добавить еще и вертолеты, и вместо взлетно-посадочных полос у нас будут вертолетные площадки. Значит, есть смысл пересмотреть и самоопределение ВПП и посадочной поверхности.

Расширяете вы правила приложения или нет не так важно, главное построить точную модель любой реальности. Оставить модель расплывчатой это не попытка удовлетворить будущие требования, это попытка оправдать собственную лень.

Итак, атрибуты. Даже если мы позволим атрибуту быть свободно определенной строкой (такой как имя), мы сможем использовать типы данных длинное имя и короткое имя. Длинное может быть определено как строка до 80 символов длиной, а короткое до 10. Нацелены они могут быть как на один тип строк реализации, так и на разные.

Поведенческие ограничения в плохой модели не выражены, а вопросы оставлены без ответов

Пора рассмотреть модель в целом поглубже. Что говорит плохая модель о поведении приложения диспетчеров, правильна ли она?

В плохой модели ассоциация контролер равна 1:. Сторона допускает нуль. В итоге мы теряем то тонкое различие междудежурнымдиспетчером, которому не назначена зона управления, ивыходнымдиспетчером.

А вот как выглядит правило R2 в плохой модели: 0..1: 0..1. Эта ни к чему не обязывающая ассоциация охватывает и выходных диспетчеров, которые не вошли в систему, и станции дежурства, которые в данный момент не используются. Вот мы с вами и потеряли ограничение, указывающее, что во время дежурства диспетчер должен быть авторизован в системе.

Если диспетчер не использует станцию дежурства, может ли он все еще курировать зону управления? На этот вопрос модель отвечает Да, поскольку эти две ассоциации на плохой модели полностью независимы друг от друга.

Если диспетчер не курирует какие-либо зоны управления, может ли он при этом быть авторизованным на станции дежурства? И хорошие, и плохие модели позволяют это. И согласно правилам применения, это нормально.

На примере таблицы Самолеты одного класса мы рассмотрели вопросы, на которые могла бы ответить модель. Попробуйте спросить у плохой модели: Какие авиадиспетчеры сейчас не работают?. Она не может ответить на этот вопрос. Она может показать, какие диспетчеры не курируют зоны управления. Но ведь эти диспетчеры могут быть на дежурстве. Можно ли исправить это, добавив атрибут статуса в класс диспетчера в плохой модели? Само собой. Однако при этом вы все равно упускаете диспетчеров со значениемвыходной, которые при этом курируют зону управления.

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

Вот один пример невалидного сценария, разрешенного в плохой модели:

Плохая модель позволяет диспетчеру находиться на дежурстве без станции дежурстваПлохая модель позволяет диспетчеру находиться на дежурстве без станции дежурства

Изображение выше выглядит нормально, за исключением диспетчера 51 (Оуэн), который курирует зону управления CZ1, но не авторизован на станции дежурства.

В четвертой (и заключительной части) мы поговорим о преимуществах и недостатках обеих моделей (да, у плохой тоже есть преимущества) и о том, как сделать хорошую модель более лаконичной.

Актуальные вакансии компанииRetail Rocket

С переводом помогали: Бюро переводовAllcorrect

Редактор: Алексей @Sterhel Якшин

Подробнее..

Перевод Как построить четкие модели классов и получить реальные преимущества от UML. Часть 2

05.10.2020 10:14:40 | Автор: admin

Вторая часть перевода статьи Леона Старра, инженера программных моделей. Первая часть вот здесь. В этой части о семантике и о том, что отличает хорошую модель.

UML и семантика, лежащая в его основе

Итак, мы рассмотрели пример лишь одного класса и заметили, что даже он охватывает сразу несколько правил. Используя табличное представление, мы получаем довольно жесткую структуру данных, поэтому можем думать о механике доступа к ним без учета конкретной реализации. Мы уже усвоили, что можем делать те или иные утверждения о том, что мы знаем, что можем вычислить, а что не можем. И все это без знания каких-то алгоритмов, диаграмм, действий или состояний. У нас просто есть схема одного класса, и этого уже достаточно, чтобы отвечать на вопросы и оценивать соответствие миру, которым планируем управлять. А представьте, что будет, когда бы добавим сотни классов и отношения.

Соблюдение ограничения идентификатора

У вас может возникнуть резонный вопрос где на самом деле применяется ограничение {I}. Модель классов устанавливает лишь требование идентификации. Когда код пишет программист или генератор модели, то должен иметь место систематический механизм обработки идентичности. При этом встроенная архитектура может использовать хэш-таблицу, а корпоративная полагаться на доступные механизмы БД для обнаружения и отклонения повторяющихся записей.

Хорошая модель

Чтобы сравнить модели, мы постараемся провести четкую разницу между хорошей моделью и плохой. Может показаться, что во мне говорит ЧСВ, когда я называю свои модели хорошими, а все остальные плохими, это довольно ошибочная практика. Поэтому давайте сконцентрируемся на ощутимых различиях, которые помогут нам улучшить методы анализа и моделирования, а как следствие создавать лучший код.

На рисунке ниже диаграмма классов условно хорошей модели

Хорошая модельХорошая модель

Некоторые части нотации выше представляют собой уже знакомый вам UML, но со своими особенностями. Поэтому мы пройдёмся по ним, рассмотрим структуру данных базовой таблицы, после чего ещё разок оценим общую картину. И потом уже сможем противопоставить хорошую модель плохой.

Классы авиадиспетчеров

В левой половине модели есть три класса: авиадиспетчер(Air Traffic Controller), выходной диспетчер (он же Off Duty Controller) и дежурный диспетчер (On Duty Controller). Вот как может выглядеть таблица суперкласса, заполненная примерными данными.

ID {I}

Имя

Дата рождения

Рейтинг

диспетчер 53

Тошико

12 июня 1975 года

A

диспетчер 67

Гвен

28 марта 1981 года

B

диспетчер 51

Оуэн

23 декабря 1974 года

C

Смотрите, что имеем. Три авиадиспетчера, для каждого из которых мы точно знаем имя, дату рождения и квалификацию (рейтинг). В таблице у значения ID есть тег {I} что это значит? Правильно, что эти значения должны быть уникальными. В таблице есть данные, которые относятся к диспетчеру, независимо от того, находится ли сейчас авиадиспетчер на своём рабочем месте или у него выходной.

Обратите внимание на текст {disjoint, complete} около отношения обобщения R1 это пара стандартных тегов UML. Это значит, что каждый объект Авиадиспетчер может быть в состоянии дежурный диспетчер или выходной диспетчер. А элемент disjoint означает, что находиться в двух состояниях сразу авиадиспетчер не может. Complete же уточняет, что каждый авиадиспетчер точно находится или на работе, или не на работе. При этом статус каждого точно определен в любой момент времени.

Само собой, невозможно, чтобы какой-то объект, находящийся на дежурстве или вне дежурства, не был объектом Авиадиспетчер. Вот и получается, что R1 не представляет собой обобщение стиля наследования это, скорее, подтипирование реляционных подмножеств. Это XOR-моделирование классов, отличный инструмент для включения логики в структуру данных.

Отношение обобщения Disjoint Complete Отношение обобщения Disjoint Complete

Дежурный диспетчер

ID {I, R1}

Время регистрации в системе

Станция {R3}

диспетчер 53

27.09.08, 15:00

S2

диспетчер 67

27.09.08, 11:00

S1

Когда диспетчер находится на дежурстве, он должен быть зарегистрирован на месте дежурства, то есть на станции. При этом и ID самой станции, и время регистрации в системе для каждого из диспетчера сохраняются, и данные эти актуальны только во время дежурства.

Посмотрите на тег {R3} в атрибуте ссылки станции. Он значит, что станция соответствует идентификатору на другой стороне R3. В нашем случае это Duty_Station.ID.

Это очередной пример механики структуры данных, независимой от платформы. Допустим, вам интересно, на какой станции зарегистрирован диспетчер 53? Из структуры нашей таблицы понятно, что для ответа на этот вопрос достаточно просто найти строку с диспетчер 53 в столбце ID, а в столбце Станция получить значение S2.

А можно пойти дальше и получить данные из таблицы станций, используя S2 как ключ. Тогда получится ответить и на более сложный вопрос, например, Кто из диспетчеров зарегистрировался в системе станции S2?. Опять ищем нужную строку в таблице дежурного диспетчера в столбце Станции и получаем значение ID диспетчер 53.

Суть этой проверки просто в том, чтобы показать, что данные в любой реализации так или иначе связаны. Но это не значит, что нам надо реализовывать свои действия в SQL и подобном. Я работаю с системами, которые удаляют ссылочные атрибут и заменяют их указателями, дескрипторами или индексами какого-либо рода.

Направления доступа для каждой связи обычно оптимизируются или отключаются при необходимости (ряд компиляторов моделей, например, сканируют язык действий, видят, что в определенном направлении связи не выполняется никаких операций записи, и пропускают код сеттера).

Есть компиляторы моделей, которые проделывают все это сами, выдавая хороший C, Java, C++ и (да-да) ассемблер. Но вот генерация какого-либо SQL это, конечно, вариант для систем типа БД.

Заметьте, что на атрибуте ID присутствует тег R1, который указывает, что он одновременно является идентифицирующим атрибутом дежурного диспетчера, соответствующего его ID в суперклассе диспетчер. Все отношения в хорошей модели склеены со ссылочными атрибутами.

Выходной диспетчер

ID {I, R1}

диспетчер 51

Как это ни странно, для выходных диспетчеров данные не хранятся, по крайней мере, мы об этом пока не знаем. Главное назначение этого класса в том, что он показывает, что время регистрации в системе и ID станций не сохраняются для тех диспетчеров, которые не на службе. Этот трюк дает нам возможность не использовать значение не применимо в наших таблицах. Что плохого в этом значении? Если вы в принципе разрешаете такие пустые значения, то для обработки особых случаев в своем коде вы напрашиваетесь на логику если то. А еще требуете место для хранения, которое на самом деле не нужно приложению.

А еще смотрите как только диспетчер уходит с работы, данные станции и времени регистрации будут удалены (или заархивированы). Так как диспетчер не может одновременно и работать, и не работать, то при миграции объекта диспетчер он или получает, или теряет данным. Вот как это отображается в таблицах.

Авиадиспетчер

ID {I}

Имя

Дата рождения

Рейтинг

диспетчер 53

Тошико

12 июня 1975 года

A

диспетчер 67

Гвен

28 марта 1981 года

B

диспетчер 51

Оуэн

23 декабря 1974 года

C

Перемещение ролиПеремещение роли

Так проводится различие между объектом диспетчер, который является суммой общих и конкретных данных, представленных в любой момент времени двумя экземплярами класса.

Зона управления(Control Zone)

Имя {I}

Трафик

Диспетчер {R2}

CZ1

12

диспетчер 53

CZ2

4

диспетчер 53

CZ3

6

диспетчер 67

Зона управления это область воздушного пространства, находящаяся в ведении одного ATC. Правило, которое мы зафиксируем, состоит в том, что каждая зона управления всегда должна быть подконтрольна какому-то диспетчеру. При этом для каждой зоны управления у нас тоже есть уникальное имя, количество трафика и назначенный для неё диспетчер. Возможно, вы придумаете и еще какие-то полезные атрибуты, скажем, объем, местоположение и прочее. Но пока для примера все же упростим.

Теперь мы можем ответить на вопрос Каким объемом трафика управляет диспетчер 53?.

Станция дежурства

ID {I}

Местоположение

Вместимость

S1

Впереди

20

S2

Впереди

45

S3

В центре

30

У каждой станции дежурства есть уникальный идентификатор, общее местоположение объекта и максимальная пропускная способность (она же - объем трафика, которым станция может управлять).

И тут уже нет никаких ссылочных атрибутов, потому что у нас уже есть один в классе дежурного диспетчера. Теперь, если надо ответить на вопрос Сколько лет человеку, авторизованному на станции S2?, то мы сможем это сделать. Для этого берем значение S2 и проверяем таблицу дежурных диспетчеров на предмет нужной строки. Если она есть, переходим в таблицу диспетчер, ищем строку с S2 и получаем из столбца Дата рождения нужное значение. Сравните её с текущей датой (она вам всегда доступна как системный параметр), проведите несложные вычисления и возраст диспетчера у вас есть.

Как я отмечал выше, такая процедура актуальна только в контексте чтения или выполнения модели. Когда вы добавляете модели состояний и действий, вы можете прогонять их в симуляторе, который управляет переходами состояний, очередями событий, совместной работой и доступом к данным/вычислениями. Как только вы сможете заставить это работать, вы сможете сгенерировать или написать код.

Программист или компилятор модели должен разработать эффективный способ склеивания всех частей вместе. Это позволяет весьма эффективно разделять ответственность между разработчиком модели (аналитиком), который определяет, какие данные надо соединить на любой из платформ, программистом (компилятором модели), который уже ищет способы реализации этих соединений для конкретных платформ.

Может показаться сложным, но это не так ведь к многим элементам модели можно применить один системный паттерн переноса, вместе с несколькими параметрами конфигурации для локальной настройки. Поэтому нескольких таких паттернов вам хватит если не для обработки всего кода сразу, то для большей его части уж точно. В кропотливой ручной разработке кода для каждого класса нет необходимости.

Иллюстрированный сценарий

Таблицы хороший способ описания абстрактной структуры данных. Но при тестировании может быть полезна иллюстрация, позволяющая увидеть, могут ли эти таблицы соответствовать конкретному сценарию реального мира.

Иллюстрированный сценарий ATCИллюстрированный сценарий ATC

На сценарии выше у нас три диспетчера, два на дежурстве, третий на заслуженном выходном. Каждый из них авторизован на одной выделенной станции, время регистрации каждого из них в системе мы тоже записали. Каждая зона управления подконтрольна одному дежурному диспетчеру. Что до выходного диспетчера, он не авторизован в системе, поэтому время его входа в систему не зарегистрировано.

Одна станция бездействует, и ни она, ни выходной диспетчер не имеют связи с зонами управления.

В общем, наша хорошая модель на самом деле позволяет обработать реалистичный сценарий.

В этом стиле диаграммы намеренно избегаются любые обозначения UML, и он очень полезен в плане избавления от так называемого аналитического паралича. Если ограничить себя безликим набором всяких фигурок и квадратиков, то можно очень легко погрузиться в какие-то придуманные вами абстракции и пропустить ситуации, которые в эти правила не вписываются. В этом есть своя ирония уделяя кучу внимания элементам модели, вы на раз-два пропускаете паттерны в реализации данных, которые могут привести к четким абстракциям.

Поэтому я всегда стараюсь рисовать диаграмму в свободной форме, потом модель UML, и уже после этого сравниваю их. Такая валидация работает в обе стороны. Можно ли заполнить таблицы данными, приведенными на иллюстрации сценария? Могу ли я создать убедительную иллюстрацию сценария, используя только данные в моих таблицах? Если я обнаруживаю новый сценарий, я проверяю, подходят ли его данные модели.

Когда я расширяю модель, я могу нарисовать и обновленный сценарий, дабы посмотреть, имеет ли он вообще смысл. Переходя то туда, то обратно, я могу обнаруживать недостатки в собственном мышлении, и в конце концов приду к четкой и согласованной модели. Плюс здесь отличная побочка в виде полезной документации.

Ещё одно преимущество в том, что пользователи и эксперты по иллюстрированной модели могут дать мне отличную детальную обратную связь, нежели по модели или диаграмме последовательности. Увы, существующие инструменты UML поддерживают лишь аспект моделирования и анализа в виде тех самых фигурок-квадратиков-линий, огромный пласт инструментов анализа еще не освоен.

Поэтому не бойтесь придумывать свои собственные значки и обозначения элементов, берите понравившиеся клипарты и используйте обозначения UML для воплощения абстракций.

В третьей части мы поговорим о правилах и ограничениях, присущих хорошей модели, а также начнём разбирать плохую модель классов.

С переводом помогали: Бюро переводовAllcorrect

Редактор: Алексей @Sterhel Якшин

Подробнее..

Перевод Как построить четкие модели классов и получить реальные преимущества от UML. Часть 3

29.10.2020 10:19:47 | Автор: admin

Продолжение цикла статей из серии "Как посмотроить четкие модели классов и получить реальные преимущества от UML". В первых двух частях (первая, вторая) мы обсудили общий принципы UML, о семантике и признаках хорошей модели. В этой части разберем как поведение системы можем быть выражено в модели.

Отношения в области управления воздушным движением

В предыдущих частях мы по большей части говорили о классах, но у хорошей модели есть еще две критически важные ассоциации, R2 и R3. Давайте подробнее про каждую из них.

Хорошая модельХорошая модель

R2: управление внутренним трафиком

Посмотрите на R2 на диаграмме, что необычного? Правильно, стиль наименования ролей немного отличается от привычного для диаграмм классов UML. В этом примере так сделано специально для плохой модели я буду использовать обычный, менее описательный стиль.

Чтобы прочитать обозначенную глагольными фразами связь, начните с одной стороны этой связи и прочитайте по порядку фразу, мощность связи и имя класса на противоположной стороне, рисунок вам в помощь.

On Duty Controller is directing traffic within zero or many Control ZoneOn Duty Controller is directing traffic within zero or many Control Zone

Если проще Дежурный диспетчер управляет движением в пределах либо ни одной, либо многих зон управления. То есть этот диспетчер может хоть и быть на дежурстве, но при этом не курировать ни одной зоны управления в текущий момент времени.

Но при этом В зоне управления есть трафик, управляемый точно одним дежурным диспетчером. То есть эта зона вообще в любой момент времени железно курируется тем или иным диспетчером, она не остается без присмотра. Причем одна зона в конкретный момент времени курируется только одним диспетчером, это важно.

Control Zone has traffic directed by one On Duty ControllerControl Zone has traffic directed by one On Duty Controller

R3: авторизация в системе

Тут видно, что дежурный диспетчер зарегистрирован ровно на одной станции. Если проще, то он может быть на дежурстве только в условиях, когда он успешно зарегистрировался в системе и для него есть свободная станция. При этом станция в любом момент времени может как управляться дежурным диспетчером, так и не управляться им. Поэтому верно будет выражение Станция управляется либо ни одним, либо одним дежурным диспетчером.

Правила, выраженные хорошей моделью

Хорошая модельХорошая модель

ОК, с элементами модели мы с вами разобрались. Давайте теперь оценим правила и ограничения, которые выражены не только отдельными элементами, а всеми, учитывая и сочетания между ними

  1. В каждый взятый момент времени авиадиспетчер либо находится на службе, либо отсутствует {R1}.

  2. Дежурный диспетчер должен быть зарегистрирован на одной станции {R3}.

  3. В любой момент времени станция может управляться или не управляться одним дежурным диспетчером, авторизованным в системе {R3}.

  4. Зона управления должна иметь свой трафик, управляемый точно одним дежурным диспетчером в каждый момент времени {R2}.

  5. Дежурный диспетчер может управлять или не управлять трафиком в одной или нескольких зонах управления в каждый момент времени {R2}.

Какие же в хорошей модели выражены поведенческие ограничения?

Мощность и фраза на каждой стороне вот что имеет главное значение для установления точных правил. Давайте зададим несколько поведенческих вопросов. Только по-честному, положите перед собой хорошую модель и попытайтесь ответить на каждый вопрос сами. Поехали.

  1. Что должно произойти, когда выходной диспетчер выходит на дежурство?

  2. Если на дежурстве остался только один диспетчер, может ли этот диспетчер уйти с дежурства?

  3. Если каждая зона управления курируется, может ли другой выходной диспетчер зарегистрироваться в системе?

  4. Если есть 5 дежурных диспетчеров и 5 станций, что нужно сделать, чтобы отключить станцию для проведения работ по обслуживанию?

  5. Если есть 3 зоны управления и 3 дежурных диспетчера, то каково максимальное число зон управления, курируемых одним и тем же дежурным диспетчером?

  6. Если предположить, что есть хотя бы один экземпляр зоны управления и только один дежурный диспетчер, то может ли этот дежурный диспетчер уйти с дежурства?

А теперь проверьте себя. Вот как правильно.

  1. Чтобы стать дежурным, необходимо войти в доступное место службы станция дежурства. Элемент выходной диспетчер будет удален и заменен новым элементом дежурный диспетчер, ссылающимся на тот же элемент диспетчера. (Добавочно обратите внимание во встраиваемых системах создание и удаление внутри модели иногда производится предварительным выделением области памяти и переключения бита, чтобы показать, действительно ли данный элемент существует. Так что существуют и другие способы реализации создания/удаления, отличные от конструкторов и деструкторов.)

  2. А вот в этом вопросе больше одного правильного ответа. Каждая из зон управления требует курирования. Допустим, у нас существует один или несколько экземпляров зоны управления, тогда ответом будет нет. Невозможно перенести элемент дежурный диспетчер, не нарушив левую сторону связи R2, если только количество экземпляров зоны управления не равно нулю. Тогда ответом будет да. Если бы был только один другой дежурный диспетчер, то зоны управления можно было бы сначала передать, но в данном случае этого нет, так что это не вариант.

  3. Да, может. Дежурный диспетчер не обязан курировать какие-либо зоны управления. Следовательно, число дежурных диспетчеров ограничивается только наличием станций.

  4. Поскольку имеется равное число станций и дежурных диспетчеров, мы можем предположить, что каждая станция используется. Поэтому нам нужно, чтобы дежурный диспетчер вышел из системы, но для этого нам нужно снять ATC с дежурства. И чтобы сделать это, мы должны сначала убедиться, что все зоны управления, руководимые этим дежурным диспетчером, сначала будут переданы другому дежурному диспетчеру.

  5. Три. Для дежурного диспетчера допустимо иметь в ведении 0 зон управления, поэтому один из них может управлять всеми тремя зонами. В этом случае у двух других дежурных диспетчеров не будет назначенных зон управления. Главное убедиться, что каждая зона управления курируется.

  6. Нет. Один из выходных диспетчеров должен сначала стать дежурным, а потом уже все зоны управления должны быть переданы.

Давайте снова с иллюстрацией, которая нужна для хорошей модели. Вот дежурный диспетчер уходит с дежурства

Диспетчер 67 снимается с дежурстваДиспетчер 67 снимается с дежурства

Заполненные таблицы диспетчеров при этом обновляются вот так:

Авиадиспетчеры

ID {I}

Имя

Дата рождения

Рейтинг

Диспетчер 53

Тошико

12 июня 1975 года

A

Диспетчер 67

Гвен

28 марта 1981 года

B

Диспетчер 51

Оуэн

23 декабря 1974 года

C

Диспетчер 67 снимается с дежурстваДиспетчер 67 снимается с дежурства

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

В четвертой статье рассмотрим пример плохой модели и ее отличий от хорошей.

С переводом помогали: Бюро переводовAllcorrect

Редактор: Алексей@Sterhel Якшин

Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru