Информационная архитектура: пример и типизация

На примере реального некоммерческого проекта разбираем проблему типизации данных в информационной архитектуре.

5-6 минут на прочтение
Информационная архитектура: пример и типизация

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

О чём статья

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

Типизация

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

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

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

Пример проекта

У нас есть реальный проект, работа над которым ведётся прямо сейчас, пока пишется эта статья. Проект некоммерческий, никаких NDA. Плюс, он попутно выполняет некоторые образовательные цели — на нём обкатывает навыки информационного и функционального проектирования талантливая Евгения Шамрай.

Информационная структура

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

Если попробовать изобразить иерархию сущностей графически, то получится что-то вроде этого:

  1. Инфоблок — самая низкоуровневая сущность, «молекула» информационной архитектуры, содержащая произвольную информацию (например, текст, цитату, изображение и тп). Из инфоблоков, собственно, и строится почти вся контентная часть продукта.
  2. Год — статическая среднеуровневая сущность, которая объединяет инфоблоки в разрезе определённых лет. Они единые для всех композиторов, но конкретные годы у конкретных композиторов могут не совпадать.
  3. Период — уникальная для каждого композитора среднеуровневая сущность, проходящая через все слои и объединяющая годы в определённый этап жизни композитора.
  4. Слой — статическая информационная сущность, объединяющая разные периоды в некий тематический срез творчества композитора. Слоёв ограниченное количество, они обязательны и одинаковы для всех композиторов.
  5. Композитор — высокоуровневая, главная сущность проекта.

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

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

Схема навигации в примере максимально простая:

  • Есть главная страница, на ней перечислены композиторы.
  • Внутри раздела каждого композитора есть список слоёв.
  • Каждый слой представлен отдельной страницей, на которой в иерархическом порядке расположены периоды, а в них — годы.

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

Под капотом

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

В нашем случае логика такова:

  1. пользователь загружает страницу конкретного слоя на сайте;
  2. браузер делает запрос к серверу, в котором указывает идентификатор этого слоя и идентификатор композитора;
  3. сервер принимает эти параметры и делает соответствующий запрос в базу данных;
  4. в результате у него появляется массив инфоблоков, которые ему теперь нужно отсортировать.

Как же происходит сортировка? Здесь тоже всё просто:

  1. все инфоблоки разделяются на периоды;
  2. периоды сортируются по порядку;
  3. внутри периодов происходит объединение инфоблоков по годам;
  4. годы также сортируются по порядку внутри периодов;
  5. внутри каждого года по порядку сортируются сами инфоблоки.

В результате в браузер пользователя прилетает многомерный массив, который потом просто разбирается на странице.

Связи сущностей

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

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

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

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

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

Проблема

Мы понимаем, что самая «насыщенная» связями сущность — это инфоблок. Мы также понимаем, что продукт будет развиваться. В нём появятся дополнительные сущности, вроде треков, плейлистов или событий. И каждый инфоблок потенциально может оказаться связанным с этими новыми сущностями.

Какая здесь появляется проблема? Мы должны спроектировать хранение связей в инфоблоке таким образом, чтобы добавление новых сущностей и связывание их с инфоблоками (как минимум с ними) не вызывало особенных проблем.

Как такое проектирование происходит обычно? А никак. Когда добавится новый тип сущности, к инфоблоку в базе данных просто будет добавлено новое поле. У каких-то инфоблоков оно будет заполнено, у каких-то — нет. Где-то в интерфейсе будет обрабатываться его отсутствие, где-то — не будет. Где-то на странице вывалится ошибка, где-то пользователь обматерит очередное обновление, где-то тестировщик обольётся кровавыми слезами.

А что, если это связь нелинейная? Не «один ко одному», а «один ко многим»? Если конкретный инфоблок может содержать в себе связь с несколькими треками? Сможем мы в одном свойстве инфоблока сохранить несколько идентификаторов треков? А если можем, то почему вообще все связи не хранить в одном свойстве?

Решение

А решения нет. По крайней мере, однозначного.

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

Боюсь, я вас запутал. Давайте немножко упрощу.

У нас, казалось бы, два варианта:

  1. Хранить каждую связь в конкретном свойстве инфоблока. Это в IA — признак «строгой» или, по другому, «сильной» типизации.
  2. Хранить все связи в одном свойстве, массивом. Обычно это отличает «слабую» типизацию.

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

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

Излишне сильная типизация в разы увеличит стоимость поддержки и развития продукта. Разработчики будут ещё сильнее, чем обычно, материть проектировщика/архитектора. Время внедрения и отладки даже маленькой новой фичи станет сопоставимо с операцией Барбаросса в 1941-ом (и, вероятно, закончится так же, — провалом).

Настоящее решение

Грамотный и осознанный баланс — вот залог действительно качественного продукта. Это в полной мере касается и информационной архитектуры.

В нашем случае я выберу комбинированный подход:

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

Или создам отдельную таблицу соответствий, но это уже совсем другая история :)

Павел Шерер, продюсер IT-решений

Канал в Telegram

Раньше тут были комментарии, но я решил не плодить сущности. Есть что сказать или спросить — велкам в телеграм-канал:

Обсудить в Telegram