UML: структура
Диаграмма классов у аналитика работает не как чертёж кода, а как модель предметной области - общий язык, на котором договариваются с бизнесом о том, что такое клиент, заказ и договор. Методы и модификаторы доступа в этой роли не нужны вовсе.
Спрашивают про типы связей и кратности, и не случайно: именно там прячутся будущие требования. Одна цифра в кратности рождает отдельный экран в интерфейсе, одна перепутанная связь - потерянную финансовую историю.
// Формулировки: «чем композиция отличается от агрегации?», «что значит 0..1?», «как смоделируешь клиента - физлицо и юрлицо?»
Связи: ассоциация, зависимость, владение
Ассоциация - устойчивая структурная связь между сущностями: у заказа есть клиент, и эта связь живёт столько же, сколько сам заказ. Зависимость рисуют пунктиром, и она слабее: один класс использует другой в момент операции и забывает о нём после.
Композиция означает сильное владение и рисуется закрашенным ромбом у целого. Удалили заказ - вместе с ним исчезли его позиции, потому что вне заказа они бессмысленны: «две штуки по 500 рублей» само по себе ничего не значит.
Агрегация - ромб незакрашенный, владение слабое. Сотрудник входит в отдел, но переживает его расформирование: его переведут в другой отдел, а не удалят вместе со старым.
// Для проектирования это прямой ответ про каскадное удаление, и ошибка тут стоит дороже всего. Поставили композицию на связь «клиент - заказы», удалили клиента по запросу на забвение - и вместе с ним стёрлась вся история продаж, которую по закону надо хранить пять лет. Проверка одна: часть имеет смысл без целого? Если да, это агрегация.
Кратность - источник требований
Кратность пишут на конце связи: 1 означает ровно один, 0..1 - ноль или один, 1..* - хотя бы один, * - сколько угодно. Выглядит как формальность, а на деле каждая запись превращается в требование к интерфейсу.
Разница между 1 и 0..1 почти всегда рождает отдельный сценарий. Если у договора ровно один менеджер, форма не сохранится без него и в списке всегда есть колонка с фамилией. Если ноль или один, нужно решить, что показывать в пустой ячейке, можно ли сохранить договор без менеджера и кто потом его назначит. Одна цифра - два экрана работы.
Связь «многие ко многим» - красный флаг, за которым почти всегда прячется самостоятельная сущность. У пары «заказ и товар» есть количество, цена на момент покупки, скидка, иногда статус позиции. Всё это атрибуты не заказа и не товара, а их связи, и значит связь на самом деле - позиция заказа.
// Практика на одну секунду: увидел «многие ко многим» - спроси, какие атрибуты у самой связи. Ответ «никаких» бывает исключительно редко, а если не спросить, атрибуты расползутся по соседним таблицам и историю цен потом не восстановить.
Наследование фиксирует тип навсегда
Сделать «Физлицо» и «Юрлицо» наследниками «Клиента» кажется естественным - они и правда разновидности клиента. Но у наследования есть свойство, о котором на схеме не написано: объект не меняет свой класс. Родился физлицом - физлицом и останется.
А в жизни тип подвижен. Физлицо оформляет самозанятость, индивидуальный предприниматель регистрирует общество с ограниченной ответственностью, юрлицо реорганизуется. При модели с наследованием такая смена означает завести новую сущность и потерять всё, что было связано со старой: историю заказов, договоры, накопленную лояльность.
Там, где тип подвижен, надёжнее связь с типом-справочником: у клиента есть поле «тип», оно меняется, а сам объект остаётся тем же самым, со своим идентификатором и историей.
// Тот же вопрос стоит задавать про любую иерархию в модели, а не про одних клиентов: может ли объект однажды перейти в другую ветку? Если да - наследование тут неуместно, каким бы стройным оно ни выглядело.
Как отвечать: «Связь Заказ - Товар помечена как многие-ко-многим. Что уточнишь?»
Первым делом спрошу, есть ли атрибуты у самой связи. Практически всегда есть: количество, цена на момент покупки, скидка, иногда статус позиции. Значит перед нами не связь, а самостоятельная сущность - позиция заказа, и её надо вынести на схему явно. Если этого не сделать, атрибуты расползутся по соседним таблицам или потеряются вовсе, и на вопрос «по какой цене мы продавали этот товар год назад» ответа не будет никогда - в карточке товара лежит сегодняшняя цена. Только после этого имеет смысл говорить про реализацию: в реляционной схеме такая связь всё равно развернётся в третью таблицу, но теперь у этой таблицы есть смысл, а не два голых внешних ключа.
Ответ идёт от смысла к реализации и называет конкретную потерю - невосстановимую историю цен, - а не общие слова про нормализацию. Разница слышна сразу.
На чём валятся
- −− Читают диаграмму классов как готовую схему базы: у «многие ко многим» и наследования прямого аналога в таблицах нет.
- −− Ставят наследование там, где тип объекта со временем меняется.
- −− Не замечают атрибуты у связи «многие ко многим» и теряют историчность.
- −− Путают композицию с агрегацией и включают каскадное удаление там, где данные обязаны выжить.
- −− Тянут в модель предметной области методы и технические поля, превращая язык бизнеса в чертёж кода.
Проверьте себя
Пять вопросов из банка по этой подтеме. Всего их 12, остальные разбираются в тренажёре.
- Чем ассоциация отличается от зависимости?A)Ассоциация рисуется пунктиром, зависимость — сплошнойB)Ассоциация устойчива, зависимость разоваяC)Ассоциация возможна только между двумя классамиD)Зависимость означает наследование
показать ответ и разбор
+B)Ассоциация устойчива, зависимость разовая// разбор: Ассоциация говорит, что объекты структурно связаны и связь живёт во времени: у заказа есть клиент. Зависимость слабее — один класс использует другой в момент операции, например принимает как параметр. На схеме ассоциация сплошная, зависимость пунктирная со стрелкой.
- Кратность 0..1 на конце связи означает, что…A)может не быть, но не больше одногоB)связь обязательна и ровно однаC)объектов может быть сколько угодноD)связь действует только при создании объекта
показать ответ и разбор
+A)может не быть, но не больше одного// разбор: Нижняя граница 0 разрешает отсутствие, верхняя 1 запрещает больше одного. Для аналитика это прямое указание разработке: поле обнуляемое, а в интерфейсе нужен сценарий «связи нет». Разница между 0..1 и 1 почти всегда рождает отдельный экран и отдельную проверку.
- Чем композиция отличается от агрегации?A)Композиция допускает только одного владельца, агрегация — многихB)Композиция рисуется между интерфейсами, агрегация — между классамиC)При композиции часть не живёт без целогоD)Агрегация означает связь один-ко-многим
показать ответ и разбор
+C)При композиции часть не живёт без целого// разбор: Композиция — сильное владение: удалили заказ, вместе с ним исчезли его позиции, потому что вне заказа они бессмысленны. Агрегация слабее: сотрудник входит в отдел, но при расформировании отдела сотрудник остаётся. Для проектирования это прямой ответ, каскадить ли удаление.
- Чем диаграмма компонентов полезна аналитику на интеграционном проекте?A)Показывает физические серверы и сетьB)Состав систем и интерфейсы между нимиC)Заменяет описание форматов сообщенийD)Отражает порядок вызовов при сценарии
показать ответ и разбор
+B)Состав систем и интерфейсы между ними// разбор: Компонентная диаграмма даёт карту ландшафта: какие системы участвуют и через какие интерфейсы связаны. На интеграционном проекте это первый артефакт, который снимает половину вопросов на старте — видно точки стыка и владельцев. Детали форматов и порядок вызовов описываются отдельно.
- В модели предметной области сделали «Физлицо» и «Юрлицо» наследниками «Клиента». Что стоит проверить?A)Поддерживает ли выбранная СУБД наследование таблицB)Одинаковы ли названия атрибутов у наследниковC)Не пишется ли имя базового класса с заглавной буквыD)Может ли клиент со временем сменить тип
показать ответ и разбор
+D)Может ли клиент со временем сменить тип// разбор: Наследование в модели предметной области фиксирует тип навсегда: объект не меняет класс. Если ИП становится юрлицом или физлицо получает статус самозанятого, придётся заводить новую сущность и терять историю. Там, где тип подвижен, надёжнее связь с типом-справочником вместо иерархии.
дальше
Теорию прочитали. Навык ставится повторением
В Сеньорчике эта подтема идёт в ежедневных сессиях: движок возвращает её, пока ответы не станут уверенными, и ведёт прогресс отдельно по каждой подтеме. Теория внутри тоже бесплатна, лимит только на количество вопросов в день.