Настал момент, когда нужно начинать проектировать приложение. И делать мы это будем, используя Entity-relationship Model
ERM - Модель данных, позволяющая описывать концептуальные схемы предметной области.
Сущности
Этот подход включает в себя два основных понятия: сущность и связь. Проще всего начать с примеров:
- Пользователь
- Кинозал
- Фильм
- Билет
- Показ фильма
Это сущности нашей предметной области, с которыми предстоит работать в коде. Как видите, понятие сущность довольно интуитивно. Но также оно обладает и рядом формальных характеристик:
- Идентификация
- Время жизни
Идентификация означает, что мы можем рассматривать сущности независимо и выделять одни среди других. Например, у нас есть разные кинозалы, и это разные сущности. Другой пример это пользователи. Даже если два человека имеют одинаковые ФИО, мы всё равно сможем их различить на основе дополнительных признаков. В программировании обычно сущностям присваивается идентификатор (суррогатный ключ), который и используется для этой цели. Чаще всего эта задача возлагается на базу данных. В нашей ситуации базы нет, поэтому мы будем задавать его самостоятельно.
const user = new User('Илон');
console.log(user.id);
// 896b677f-fb14-11e0-b14d-d11ca798dbac
// User.js
import uuid from 'uuid/v4';
class User {
constructor(name) {
this.id = uuid();
this.name = name;
}
}
Библиотека uuid
позволяет генерировать уникальный идентификатор, который можно использовать для идентификации. Кстати uuid очень полезная штука, может пригодиться в некоторых типах задач.
Время жизни означает, что наша сущность в какой-то момент появилась и когда-то может исчезнуть.
Связи
Между собой сущности образуют связи. Например, человек может быть владельцем нескольких машин, но машина может принадлежать только одному человеку. Пользователи Хекслета проходят много курсов, каждый курс доступен всем пользователям.
Таким образом можно выделить три основных типа связи: один к одному (o2o), один ко многим (o2m) и многие ко многим (m2m).
Выше представлена диаграмма Entity-Relationship. Она входит в стандарт UML и неплохо помогает понять то, какие сущности составляют вашу предметную область и как они друг с другом связаны.
Что можно сказать глядя на диаграмму?
- В одном зале может быть много показов фильмов;
- Один фильм может быть показан много раз;
- Фильмы и залы связаны друг с другом как "многие ко многим". То есть один фильм показывается в разных залах, а в одном зале идут разные фильмы.
Всё это довольно очевидно и соответствует нашему опыту посещения кинозалов. В других предметных областях это уже не так просто, и то, как вы проектируете сущности и их связи, имеет сильное влияние на ваше приложение. Общее правило такое, чем больше связей и чем более они разнообразные, тем сложнее приложение. Часто бывает такое, что программисты "закладываются на будущее" (которое не факт, что наступит) и пытаются делать чуть ли не все связи m2m. Чаще всего такой подход оказывается примером over-engineering (гиперпроектирование), другими словами, не надо добавлять сложности там, где нет реальной потребности.
Кроме влияния на логику работы, связи также сильно влияют на способ хранения сущностей в базе данных. Например, в реляционных базах данных, связь m2m всегда подразумевает наличие промежуточной таблицы. В свою очередь рефакторинг базы данных не такое простое занятие, как изменение кода.
Пример
На Хекслете есть курсы. Каждый курс состоит из уроков. Урок не может существовать без курса. Вот как может быть представлена эта модель в коде:
const course = new Course('JS: DDD');
const lesson1 = new Lesson(course, 'Введение');
const lesson2 = new Lesson(course, 'Модель Сущность-Связь');
Передача курса в конструктор удобна по двум причинам. Сразу становится видна и понятна связь урока с курсом. А также на уровне языка заложено бизнес-правило, что урок не может существовать без курса.
Объекты-значения (Справочники)
Кроме сущностей в предметной области всегда есть и значения, или, как их обычно называют, объекты-значения. В отличие от сущностей у них нет идентификации. Возьмём такое понятие как деньги (Money). Если мы не являемся казначейством, то нужно ли нам отличать одни 100$
от других 100$
? Вероятно, нет. Для нас не существует сущности 100$
, всё, что имеет значение, это номинальная стоимость этих денег, другими словами, в случае объектов-значений сравнение происходит не по идентификации, а на основе фактического значения. То же самое применимо ко всем справочным данным. Имена стран (производители фильмов), адреса, список городов и многое другое.
Важно понимать, что это не абсолютная истина. Будет ли какое-то понятие сущностью или значением зависит от конкретной предметной области.
Остались вопросы? Задайте их в разделе «Обсуждение»
Вам ответят команда поддержки Хекслета или другие студенты
- Статья «Как учиться и справляться с негативными мыслями»
- Статья «Ловушки обучения»
- Статья «Сложные простые задачи по программированию»
- Вебинар «Как самостоятельно учиться»
Для полного доступа к курсу нужен базовый план
Базовый план откроет полный доступ ко всем курсам, упражнениям и урокам Хекслета, проектам и пожизненный доступ к теории пройденных уроков. Подписку можно отменить в любой момент.