Объектная модель данных и старый добрый реляционный SQL. Как объединить эти разноплановые вещи?
Уже давно все пользуются объектно-ориентированным подходом, и SQL сервер, способный не только хранить, но и перерабатывать информацию, давно вошел в нашу жизнь. Но когда ОО (Объектно – Ориентированный) язык программирования начинают применять для работы с базами данных, как правило изменяют ОО-подходу.
Можно конечно пользоваться специальными ООСУБД, однако, по нашему мнению, еще рано говорить о том, что ООСУБД являются серьезными конкурентами таким продуктам, как например Oracle и MS SQL. Слишком много ресурсов вложено в эти продукты, и их реноме таково, что во многих случаях достаточно одного только имени. Существует другое решение, воспользовавшись которым можно не отказываться от проверенных временем СУБД.
Разрабатывая систему NEXUS, нам удалось использовать MS SQL Server как хранилище не записей, а объектов. Решение получилось очень необычным, можно без преувеличения сказать, уникальным, и ниже мы опишем основные принципы архитектуры системы.
Первое, с чего надо начать, это то, что на MS SQL Server в системе NEXUS хранятся не только данные, но и вся бизнес-логика, все правила работы с объектами. Все – следует понимать именно как абсолютно все. Клиентское приложение – это только программа просмотра (браузер). Когда пользователь вызывает, например, свойство накладной «Отгрузить», то на сервер передается команда вызвать свойство с определенным именем у определенного объекта. Про то, что при отгрузке накладной, в частности, уменьшается количество товаров на складе, изменяется баланс клиента, клиентское рабочее место даже не подозревает.
Отсюда следуют сразу три важные свойства системы. Во-первых, ее крайняя экономность в трафике между сервером и рабочей станцией. В большинстве случаев пересылаются только короткие команды. Поэтому NEXUS прекрасно работает по медленным линиям – через RAS (Remote Access Service) и Internet. Во-вторых, это гарантия целостности данных. Если программа на рабочей станции «сошла с ума», то она не сможет «испортить данные». Более того, случайно запущенная в сети старая версия программы будет работать по новым правилам, так как собственно правил в себе не содержит! Наконец, в приведенном выше примере с накладной, программа вызывает только некую процедуру «Выполнить свойство». Она не имеет доступа к количествам товаров на складе, к информации из накладной. Более конкретно, она имеет доступ только к четырем буферным таблицам и может вызывать около 20 процедур. Это все. Никакого доступа непосредственно к хранимым данным программа не имеет. Что это означает для администратора? Это означает, что несанкционированный доступ к данным невозможен не только через клиентское приложение, но и через средства низкого уровня (ODBC, Db Lib?), если только не известен пароль администратора.
Теперь о том, как информация хранится. Все, что есть в системе – это документы. Документы всегда относятся к какому-нибудь классу. Между классами существуют обычные для ОО-подхода отношения (наследования). Вместо конструкторов, деструкторов и функций существует механизм событий, который вызывает процедуры – обработчики событий в порядке, зависящем от иерархии классов.
Пусть, например, на документе, представляющем пользователя, нажата правая кнопка мыши (получить список свойств). Первым будет вызван обработчик событий класса «Документ», от которого произведены все другие классы. Этот обработчик декларирует наличие свойств, которыми обладают все документы в системе, в частности, свойство «история изменений» (кто, как и когда изменил какие поля), «замечания к документу» (произвольный текст) и ряд других. Далее вызывается обработчик класса «Сотрудник», который добавит свойства просмотра и редактирования. От класса «Сотрудник» произведен класс «Пользователь», и в этот момент будут добавлены свойства, которыми обладают не все сотрудники, а только пользователи – дать возможность регистрации, вывести список привилегий и ряд других.
Каждый обработчик события представляет собой отдельную хранимую процедуру в терминологии SQL Server. Поэтому модифицировать систему так, чтобы, допустим, при отгрузке накладной еще добавлялась запись в определенный журнал, не означает изменить существующую процедуру отгрузки, а лишь добавить новую. Это позволяет расширять систему, не модифицируя ее существующие части.