Pull to refresh

Архитектура предметной области в CMF/CMS системах

Reading time 6 min
Views 3.8K
Практически любая информационная система характеризуется наличием системы хранения и оперирования данными. Возьмем, к примеру, обычные веб-сайты. Для их создания обычно используются какие-либо готовые системы (фреймворки или уже готовые CMS), в которых изначально уже заложена какая-то концепция по работе с данными, установившаяся предметная область. Обычно, если разработчик хочется добавить на сайте раздел новостей, он добавляет в интерфейсе CMS компонент, информационный блок, шаблон и т.п. Суть всех этих конструкций одна — создать сущность в БД для хранения (либо каком-то ином хранилище). В итоге имеется реляционная база данных и, зачастую, какой-то объектно-ориентированный обвес, реализующий связку объект-атрибуты-свойства-методы — реализуется предметная область.

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

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

Представьте себе идеальное приложение, в котором все строится на отлаженной предметной области. Её архитектор (обычно, специалист по каким-либо системам хранения данных) заранее знает будущее приложение и создает хранилище для него по такому принципу, что покрывает 2 из 3-х уровней разработки приложения: уровень хранения и уровень алгоритмов. Дальнейшее создание функционала веб-разработчиком является лишь вопросом бизнес-задачи (вывести все сообщения блога, выбрать все комментарии к текущему сообщению блога и т.п.).

А разработчику не очень важно знать, как именно организована структура хранения данных на уровне SQL (структура для хранения данных реализована в виде самих данных, реализована стандартными средствами СУБД или смешана). Он оперирует понятиями объект-атрибут. Предметную область в этом случае можно представить графом. Помимо стандартных характеристик объекта (атрибуты (информация), связи) у терминологического поля имеются:
  1. можно организовывать не только связи, но и взаимодействия (триггеры);
  2. маршруты графа (замкнутые, незамкнутые, часто меняются);
  3. отказ от необходимости знать, как выглядят SQL-таблицы на самом деле;
  4. методы (добавить пользователя, отправка письма по почте, а в другой объект что-то добавить).


Объектная модель


Объектная модель должна позволять выбрать множество A по известным параметрам B: A(B). Вот несколько практических примеров:
  • список пользователей, у которых возраст > 20: user(user.age>20);
  • список подарков у пользователей с возрастом более 20: gifts(user.age>20).

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

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

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

Рассмотрим пример, наша предметная область изображена в виде графа.

image


На графе описывается ситуация с сотовой связью: оператор — регион — тариф — симкарта(номер) — контракт — телефон — брэнд — человек — где прописан. Пример запроса:
  • регион(человек.возраст>20, brand=Nokia);
  • регион(человек.возраст>20).


Связи


Клиентское приложения отправляет параметры объектов «Человек» и «Brand» на объектный сервер, который по ним должен построить связь и выдать список регионов, в которых проживают такие люди. Как видим из графа, существует несколько вариантов его обхода, чтобы выявить связи. Для вычисления последовательно строится дерево, корнем которого является искомый объект (Регион), а ветками — все последовательно связанные объекты. Построение происходит в несколько итераций от искомого объекта в глубь графа. На нашем примере дерева таких уровней 4. В дереве каждый объект участвует только единожды. После построение на нужных узлах отмечаются выставленные разработчиком параметры, лишние узлы отсекаются. В примере с выборкой региона ветка «Контракт-Оператор» не потребуется, поэтому она не учитывается. А по выставленным «Brand» и «Человек» объектный сервер однозначно сможет определить Регион.

image


Итак, мы выяснили, как строятся возможные пути между объектами для вычисления функции A(B). Осталось понять, какой именно маршрут выбирается объектным сервером. Тут все очень просто: маршрут выбирается наиболее короткий на основании весов объектов, в нем участвующих. Логично, что самостоятельный объект имеет наибольший вес, равный 1. Объект-связка имеет вес 1/2. Другие сущности хранилища так же имеют подобные веса.

Типы объектов


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

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

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

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

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

Выводы


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

Эпилог


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

В ближайшее время Mozart скорее всего будет опубликован с открытыми исходными кодами под одной из свободных лицензий.
Tags:
Hubs:
+39
Comments 58
Comments Comments 58

Articles