- Все статьи цикла:
- Информационная архитектура: краткий экскурс
- Информационная архитектура: пример и типизация (вы здесь)
- Информационная архитектура: модели (coming soon)
- Информационная архитектура: сущности (coming soon)
Дисклеймер: если вы не знаете, что такое информационная архитектура, то крайне рекомендую сперва прочитать вот этот мой пост, а потом уже вернуться сюда. Иначе крайне высока вероятность того, что изложенный ниже текст не принесёт вам особенной пользы.
О чём статья
В первую очередь, речь пойдёт о проблеме информационной типизации в IT-проектах. В частности — о типизации конкретных свойств информационных сущностей. Однако рассказать об этом в отрыве от конкретики вряд ли получится, а если и получится, то выйдет долго и скучно. Поэтому в этой статье мы сперва разберём конкретный пример реального проекта, а уже затем сделаем кое-какие выводы.
Типизация
В языках программирования есть понятия «сильной» и «слабой», «статической» и «динамической» типизаций. Если несколько упростить, то «типизация» диктует, как именно заполняются переменные в коде: можно ли одну и ту же переменную в разные периоды времени наполнить то текстом, то числом, то датой и тд.
Если с языками программирования всё более или менее ясно, то при работе с информационной архитектурой продукта типизацией мало кто заморачивается. Хотя именно она часто определяет часть возможностей к развитию продукта.
Информационные архитекторы, чаще всего, выполняют свою работу «по наитию» (разумеется, называя это «логикой» и «опытом»). Наверное, в этом нет ничего плохого или критичного — так делают все, и даже сложные продукты как-то создаются, живут и развиваются. Однако мы же хотим сделать мир лучше и совершеннее, не правда ли?
Пример проекта
У нас есть реальный проект, работа над которым ведётся прямо сейчас, пока пишется эта статья. Проект некоммерческий, никаких NDA. Плюс, он попутно выполняет некоторые образовательные цели — на нём обкатывает навыки информационного и функционального проектирования талантливая Евгения Шамрай.
Информационная структура
В проекте есть несколько информационных сущностей, у каждой есть некоторые свойства. Все сущности связаны между собой: какие-то напрямую, какие-то опосредованно.
Если попробовать изобразить иерархию сущностей графически, то получится что-то вроде этого:
- Инфоблок — самая низкоуровневая сущность, «молекула» информационной архитектуры, содержащая произвольную информацию (например, текст, цитату, изображение и тп). Из инфоблоков, собственно, и строится почти вся контентная часть продукта.
- Год — статическая среднеуровневая сущность, которая объединяет инфоблоки в разрезе определённых лет. Они единые для всех композиторов, но конкретные годы у конкретных композиторов могут не совпадать.
- Период — уникальная для каждого композитора среднеуровневая сущность, проходящая через все слои и объединяющая годы в определённый этап жизни композитора.
- Слой — статическая информационная сущность, объединяющая разные периоды в некий тематический срез творчества композитора. Слоёв ограниченное количество, они обязательны и одинаковы для всех композиторов.
- Композитор — высокоуровневая, главная сущность проекта.
Если рассматривать эту модель как плоскую, то получается, что внутри одного композитора находится произвольное количество инфоблоков, которые объединяются в годы, которые объединяются в периоды, которые объединяются в слои.
У каждой сущности есть свои свойства. Мы не будем детально перечислять и описывать все такие свойства, так как это выходит за рамки темы статьи. Но мы помним, что у каждой сущности в проекте всегда есть как минимум одно свойство: внутренний идентификатор (уникальный для каждого экземпляра этой сущности).
Навигационная модель
Схема навигации в примере максимально простая:
- Есть главная страница, на ней перечислены композиторы.
- Внутри раздела каждого композитора есть список слоёв.
- Каждый слой представлен отдельной страницей, на которой в иерархическом порядке расположены периоды, а в них — годы.
Внутри каждого года может находится произвольное количество инфоблоков — я не стал их отображать на схеме, чтобы не усложнять восприятие:
Под капотом
Важно понимать, как именно будет работать наша система — без этого зачастую невозможно выяснить все свойства и связи сущностей. Здесь мы уже одной ногой ступаем на зыбкую почву дизайна данных, но без этого никак. Мы должны построить схему обмена и формирования информации в нашем продукте.
В нашем случае логика такова:
- пользователь загружает страницу конкретного слоя на сайте;
- браузер делает запрос к серверу, в котором указывает идентификатор этого слоя и идентификатор композитора;
- сервер принимает эти параметры и делает соответствующий запрос в базу данных;
- в результате у него появляется массив инфоблоков, которые ему теперь нужно отсортировать.
Как же происходит сортировка? Здесь тоже всё просто:
- все инфоблоки разделяются на периоды;
- периоды сортируются по порядку;
- внутри периодов происходит объединение инфоблоков по годам;
- годы также сортируются по порядку внутри периодов;
- внутри каждого года по порядку сортируются сами инфоблоки.
В результате в браузер пользователя прилетает многомерный массив, который потом просто разбирается на странице.
Связи сущностей
Как я уже говорил, все сущности связаны. Но связь эта не всегда прямолинейна.
Чтобы связать информационные элементы, к одной сущности нужно прикрепить ссылку на другую. В нашем случае — к «дочерней» нужно прикрепить ссылку на «родительскую». Делать это правильнее (и проще) всего с помощью как раз с помощью идентификаторов.
- Композитор — главная и независимая сущность.
- Слои единые для всех композиторов и вообще — для всего проекта, они ни от чего не зависят.
- Период у нас уникален для каждого композитора, а значит, ссылается на него (имеет в своих свойствах идентификатор того композитора, которому принадлежит).
- Годы тоже едины для всего проекта, независимы от остальных сущностей.
- И только инфоблоки, как низшая сущность, зависят от всех остальных информационных элементов системы. У них в свойствах прописаны идентификаторы всех остальных сущностей.
Вот так выглядит схема зависимостей в нашем примере:
Больше всего свойств со связями в нашем случае будет именно у инфоблоков. Очевидно, что каждый раз, когда нам понадобится связать инфоблок с композитором, слоем, периодом или годом, мы просто прописываем ему соответствующий идентификатор в соответствующее поле.
Проблема
Мы понимаем, что самая «насыщенная» связями сущность — это инфоблок. Мы также понимаем, что продукт будет развиваться. В нём появятся дополнительные сущности, вроде треков, плейлистов или событий. И каждый инфоблок потенциально может оказаться связанным с этими новыми сущностями.
Какая здесь появляется проблема? Мы должны спроектировать хранение связей в инфоблоке таким образом, чтобы добавление новых сущностей и связывание их с инфоблоками (как минимум с ними) не вызывало особенных проблем.
Как такое проектирование происходит обычно? А никак. Когда добавится новый тип сущности, к инфоблоку в базе данных просто будет добавлено новое поле. У каких-то инфоблоков оно будет заполнено, у каких-то — нет. Где-то в интерфейсе будет обрабатываться его отсутствие, где-то — не будет. Где-то на странице вывалится ошибка, где-то пользователь обматерит очередное обновление, где-то тестировщик обольётся кровавыми слезами.
А что, если это связь нелинейная? Не «один ко одному», а «один ко многим»? Если конкретный инфоблок может содержать в себе связь с несколькими треками? Сможем мы в одном свойстве инфоблока сохранить несколько идентификаторов треков? А если можем, то почему вообще все связи не хранить в одном свойстве?
Решение
А решения нет. По крайней мере, однозначного.
Да, мы можем в одном свойстве хранить сразу несколько (сколько угодно) связей. Но упростит ли нам это задачу? Не будет ли слишком «дорогим» с точки зрения программных ресурсов разбор такого «комплексного» свойства? А если наших инфоблоков несколько миллионов? Справится ли сервер с необходимостью получить их все, выяснить, какие из них относятся к конкретному композитору и конкретному слою?
Боюсь, я вас запутал. Давайте немножко упрощу.
У нас, казалось бы, два варианта:
- Хранить каждую связь в конкретном свойстве инфоблока. Это в IA — признак «строгой» или, по другому, «сильной» типизации.
- Хранить все связи в одном свойстве, массивом. Обычно это отличает «слабую» типизацию.
«Слабая» типизация подразумевает больше свободы, «строгая» — больше стабильности. Но при этом каждая из них, возведённая в абсолют, может уничтожить все плоды ваших усилий.
Слишком слабая типизация приведёт ваш продукт к тому, что простая операция по извлечению и сортировке нужных инфоблоков будет занимать непозволительно много времени. Сайт будет грузиться медленнее, конверсия будет снижаться, бизнес (или кто там у вас вместо него) окажется недоволен.
Излишне сильная типизация в разы увеличит стоимость поддержки и развития продукта. Разработчики будут ещё сильнее, чем обычно, материть проектировщика/архитектора. Время внедрения и отладки даже маленькой новой фичи станет сопоставимо с операцией Барбаросса в 1941-ом (и, вероятно, закончится так же, — провалом).
Настоящее решение
Грамотный и осознанный баланс — вот залог действительно качественного продукта. Это в полной мере касается и информационной архитектуры.
В нашем случае я выберу комбинированный подход:
Для связей, которые могут понадобиться при «выборке» инфоблоков из базы данных, я выберу отдельные свойства. В нашем случае это будут уже упомянутые композитор, слой, период и год. Остальные, существующие или потенциально возможные, я запихну в отдельное свойство массивом.
Или создам отдельную таблицу соответствий, но это уже совсем другая история :)
- Все статьи цикла:
- Информационная архитектура: краткий экскурс
- Информационная архитектура: пример и типизация (вы здесь)
- Информационная архитектура: модели (coming soon)
- Информационная архитектура: сущности (coming soon)