К. Сунцов
Компания АйТи, тел.: (095) 127-9010
Введение
Вот уже более трех лет коллектив разработчиков, в состав которого входит и автор, занимается разработкой бухгалтерской офисной сетевой системы (что и легло в основу аббревиатуры БОСС). За это время мы прошли все стадии процесса, который обычно называют программированием в архитектуре клиент-сервер (К/С). Мы были не новичками, имея за плечами опыт работы с Clipper, Clarion, C++, создание одиночных программ для автоматизации различных подразделений бухгалтерии. Оценивая все те трудности, с которыми мы столкнулись за эти три года, можно сделать вывод, что программирование в архитектуре К/С - это не просто количественный переход от разработки настольных (локальных) баз данных (БД) к большему числу взаимосвязанных модулей, а качественно новая технология создания программного обеспечения (ПО). Переход на эту технологию потребовал от нас перестройки всех этапов создания ПО - от подготовки программистов и пользователей, до разработки проектной и технической документации, выбора платформы и инструмента разработки.
Сервер
Архитектура К/С всегда предполагает наличие некоторого ПО, выполняемого на центральной ЭВМ - сервере. Три года назад мы сделали ставку на дешевое, но достаточно производительное ПО - сетевую ОС Novell NetWare и NetWare SQL 3.0. Этот SQL-сервер поддерживал стандарт ISO-89 (Уровень 2). Основные достоинства этого сервера - хранимые процедуры и декларативная ссылочная целостность. Некритичные требования к аппаратному обеспечению - 8(16) Мб ОЗУ при 25(50) пользователях и размере БД до 4 Гб - делают этот сервер достаточно привлекательным. Этот сервер позволяет строить распределенные БД и одновременную работу с несколькими словарями БД с различных рабочих станций (что нам позволяет достаточно просто вести различные проекты на одном сервере). Появившаяся в конце 1994 года новая версия NetWare SQL - Scalable SQL 3.01 (сервер сменил название в связи с отделением от фирмы Novell компании Btrieve Technologies, которая, в частности, продожает разработку NetWare SQL) имеет более высокую производительность. В ней был исправлен ряд досадных ошибок.
Клиент
Придерживаясь стратегии создания дешевого ПО, мы начали разработку клиентской части для использования в DOS. К сожалению, основным недостатком NetWare SQL является отсутствие инструмента разработки. Первоначально, столкнувшись с этой проблемой, мы использовали SDK, поставляемый с сервером, и библиотеку классов TurboVision (TV) фирмы Borland, поставляемую с компилятором С++ 3.1. Были разработаны две библиотеки классов, первая на основе SDK (условное название SOURCE) и вторая на основе TV (условное название USERS).
Рисунок 1.
Структура библиотеки SOURCE
Рисунок 2.
Структура библиотеки USERS
Основными классами библиотеки SOURCE являются sSqlManager (контекст запроса), sFields (поле БД), sTable (состоящий из sField и выполняющий передачу данных между клиентом и сервером) и sStatement (позволяющий строить SQL-запросы). Примеры типичного использования двух последних классов:
sS-tatement() + Update + "my_table" + Set + "my_field" + value + Where + "my_field" + EQ + Value(...) + Do_Sql;
- -эта последовательность операторов строит и выполняет UPDATE
sT-able t("Select * From my_table"); char buff[1000]; SCAN (t) *buff = С|Т; printf(t >> buff); ENDSCAN
- -эта последовательность операторов выполняет печать запроса на экран.
Основными классами библиотеки USERS являются sWindow (скроллируемый список просмотра) и sDialog (форма редактирования). Примеры типичного использования этих классов:
sWindow ("Select * from my_table");
- -создает окно для показа результата запроса.
sD-ialog ("Select * from my_table"){ setField(TRect(0,0,10,1),"1"); setField(TRect(0,2,10,3),"2"); setField(TRect(0,4,10,5),"3", sdLookUp,lookup("Select * fromdetail")); defaultButton(); };
- создает форму редактирования.
Используя эти две библиотеки, можно достаточно быстро строить приложение. Но оказалось, что данный подход не оправдан. Сложность программирования на С++ (включая использование TV) - большой объем кода, сложность его модификации (сопровождения) - привели к пониманию, что нужен некоторый инструмент, выполняющий набор стандартных операций и позволяющий вести быструю разработку силами традиционных программистов (сильных в предметной области).
На основе анализа уже существующих программ было выработано несколько основных требований к будущему инструменту. Это, прежде всего, возможность коллективной разработки, многократное использование кода (объектов). На современном этапе наиболее прогрессивный метод создания ПО - это использование ресурс-файлов, когда, меняя некоторый внешний файл (обычно текстовый), можно сменить (без перекомпиляции программы) всю логику ее выполнения. Мы выбрали этот подход, но возникает вопрос, где хранить этот ресурс-файл? В нашем случае использования SQL-сервера естественный ответ - в таблицах самой БД: это ускорит работу, уменьшит объем кода (один и тот же класс используется для работы с данными и с ресурсами). Там, где расположены данные, мы стали хранить логику и обработки и отображения этой информации! Для выполнения подобного рода приложений локальный диск необязателен - это гарантирует запуск именно той версии, которая необходима. Она находится на сетевом диске и связана именно с той БД, для которой разрабатывалась. Это уменьшает вероятность ошибок, возникающих вследствие использования неправильных версий ПО.
В результате такого выбора мы смогли решить сразу несколько проблем - обеспечить коллективный доступ, разбивку по проектам, многократность использования одного элемента(объекта) приложения разными программистами и защиту от несанкционированного доступа - т.е. все то, что дает реляционная СУБД. Результатом работы над созданием инструмента стало появление пакета под общим названием SQL-Граф.
Рисунок 3.
Структура пакета SQL-Граф.
SQL-Граф разработан на основе библиотек SOURCE и USERS. В результате сохранился старый подход - программирование на С++. Все, что лежит в ресурс-файлах, доступно программисту на С++ - он даже может создавать свои классы, наследуя их от объектов, созданных через SQL-Граф. Но для большинства наших разработчиков основной путь - это использование трех программ: Designer, Admin и RunTime. Центральная программа - Designer. Это, по сути, редактор ресурс-файла. Используя ее, можно строить формы, отчеты, управляющие элементы, систему контекстной помощи, разрабатывать и отлаживать процедуры и т.д. Результатом будет информация, записанная в таблицы БД. Admin - средство администрирования БД и интерактивной работы с SQL-сервером. RunTime - программы запуска приложений. Приложение представляет из себя набор связанных SQL-таблиц, в которых хранится вся информация (логика выполнения), и по мере ее использования она переписывается в расширенную память компьютера для ускорения работы (не надо лишний раз считывать ресурс с сервера). Фактически, это означает динамическую сборку приложения в момент его выполнения.
Рисунок 4.
Структура создания приложений с помощью Designer.
Любой элемент приложения является объектом, хранимым в БД. Для его создания требуется знание SQL - только управляющие элементы (меню, кнопки и т.п.), которые объединяют отдельные объекты приложения, не связаны напрямую с запросами к БД. Можно сказать, что девиз SQL-Граф - отобразить любой запрос к БД в окне или отчете. Большинство современных средств разработки уводит разработчика от SQL - в них предложения SQL строятся с помощью "мыши". Это удобно для неподготовленного, но достаточно грамотного пользователя (все равно требуется знание структуры БД, а это уже предполагает некоторое представление об SQL). Но так ли это удобно для программиста-профессионала? Построить сложный запрос с помощью "мыши" (например, с подзапросом, с OUTER JOIN, UNION, GROUP BY и т.п.) или просто невозможно, или так сложно, что проще отказаться от мысли чего-то добиться таким способом. При этом надо учесть, что не все запросы можно подготовить, используя механизм VIEW. Этот подход визуального построения запросов еще более удивляет - "говорить" с SQL-сервером и не знать его азбуку! Этот язык специально разрабатывался для упрощения работы с БД: анализируя SQL-запрос, SQL-сервер может построить оптимальный путь его выполнения.
Рисунок 5.
Структура стандартного приложения.
В нашем инструменте для упрощения построения запросов используются и заранее подготовленные шаблоны в соответствии с синтаксисом SQL, и возможность доступа к элементам БД (таблицам, полям). Мы сразу приняли простой критерий "хорошо" спроектированной реляционной БД: можешь написать простой и быстрый запрос - значит, все нормально, а задача инструмента - построить по нему окно (форму), вывести отчет.
Подготовленные таким образом объекты связываются через систему управляющих элементов в приложение. Это означает, что процесс создания приложения идет по этой схеме - это просто обозначение пунктов меню и заполнение их оконными или отчетными элементами (фактически, запросами к БД, что, собственно, и пишет разработчик). Конечно, так можно создать только простое, четко формализованное приложение. Более сложная логика реализуется через процедуры.
Рисунок 6.
Горизонтальные и вертикальные связи между проектами.
SQL - непроцедурный язык. Поэтому в инструменте используется собственное расширение SQL. В нем поддерживаются все стандартные конструкции ветвления языков программирования (IF THEN ELSE, WHILE, DO WHILE, SWITCH), собственные конструкции для работы с запросами к БД (SCAN, LET, _UPDATE), процедуры, макросы и многое другое. На основе этого языка можно строить процедуры связи оконных элементов, отличной от принятой в управляющих элементах, выполнять различные расчетные задачи. А использование макросов позволяет даже создать собственное подмножество языка, в частности, строить запросы к БД на русском языке. Примером использования может служить короткая процедура:
Scan Select * From my_table Execute Begin Preview @1|@2|@3; End.
Эта процедура выводит все записи из таблицы для дальнейшей печати в окно для просмотра.
У объектов SQL-Граф нет наследования. Но так как все они построены на базе С++, то имеют единый интерфейс и внесение изменений сразу сказывается на всех ранее разработанных объектах. Хотя это и создает некоторую жесткость построения как логики программы, так и ее вида, но при этом достигается общий фирменный стандарт и упрощается внедрение (обучение и освоение конечным пользователем) и сопровождение разработанного ПО. Разработчикам приходится следить только за структурой БД и запросами к ней. Наличие же открытого инструмента разработки позволяет без труда вносить новые возможности (как пункты меню) в уже работающее приложение, без опасений разрушить другой код. Это может сделать даже и конечный пользователь, обычно администратор БД. Написав запрос на SQL, можно тут же вывести его на экран, а затем и распечатать. При необходимости этот запрос можно внести в приложение и как пункт меню.
Подобный подход позволяет строить различные рабочие места простой перекомпоновкой уже работающих элементов. При этом приложение может настраиваться под конкретного пользователя в зависимости от его полномочий в БД. Можно использовать только один элемент, который, например, во всех приложениях отвечает за справочник продукции и т.п. Обычно подобные задачи решают через использование общих библиотечных модулей. Но модули надо описывать, им надо передавать параметры, надо постоянно поддерживать их актуальность (обычно этим занимаются специальные пакеты типа PVSC фирмы INTERSOLV). В нашем же случае это просто имя объекта. При этом для смены объекта (логики программы или исправления ошибки) достаточно сохранить новую версию в БД, не перетранслируя программу. Это упрощает сопровождение уже работающего ПО даже у удаленного пользователя. Все программисты знают, как тяжело разобраться в коде другого программиста. При использовании SQL-Граф программист, даже не очень осведомленный в конкретной предметной области, может внести необходимые изменения в приложение, разработанное его коллегой (что уменьшает число командировок и зависимость от конкретного разработчика).
Средства отладки
Основа инструмента - SQL и его расширения, поэтому отлаживаемым элементом является SQL-запрос. В любой момент создания объекта можно выполнить ??его запрос, проверив его правильность. При выполнении программы есть возможность включить показ SQL-запросов и посмотреть, что выполняется в данный момент. Можно записать в специальную таблицу (с указанием времени выполнения) все запросы к БД - весь внутренний цикл приложения для его трассировки и оценки производительности системы.
Сравнение с существующими инструментами
SQL-Граф не помогает проектировать структуру БД. Для этого мы используем Design/IDEF фирмы Meta Software, CASE фирмы ORACLE и ERwin фирмы Logic Works. Сейчас мы, параллельно с работой над Scalable SQL, разрабатываем приложения с использованием AS/400 и ORACLE7. Для работы с этими серверами мы приобрели SQLWindows 5.0 (фирма GUPTA) и Developer/2000, Designer/2000 (фирма ORACLE). Это универсальные инструменты, на которых можно написать любое по сложности приложение. Не будем оценивать плюсы и минусы этих средств. Преимущество SQL-Граф по сравнению с этими инструментами, пожалуй, только одно - это уже готовая жесткая система для разработки бухгалтерских приложений. Используя же TeamWindows и Developer/2000, надо еще наработать тот критический объем общих объектов, после которого программирование из рутины превращается в творчество (оба инструмента предлагают объектный подход, так что это вполне возможно). При этом слабостью SQLWindows, как ни странно, можно назвать его относительно слабую связь с БД, что удивляет, так как этот инструмент, вроде бы, ориентирован именно для работы с СУБД. В инструментах ORACLE эта связь проработана вполне приемлемо. Далее, если бы мы попытались, по возможности, упростить горизонтальные связи между проектами, то в SQLWindows проект со своими объектами полностью независим. А это странно - ведь хотя проекты (склад, зарплата и т.п.) и разделены логически (их ведут разные программисты), но БД одна, и они связаны через общие таблицы. И в результате в каждом проекте - свой элемент, который делает то же самое, а в случае его изменения (структуры БД, логики обработки) работа проводится в двух или более местах. Все это очень усложняет коллективную разработку приложений. В этом плане нам очень понравились инструменты фирмы ORACLE, хотя из-за наличия пользовательских схем в самой БД сложно вести несколько проектов для разных заказчиков (сложно моделировать механизм ролей, единственный путь - работать под одним именем, но тогда обезличиваются объекты).
Недостатки
Основной недостаток SQL-Граф - его одноплатформенность. Сейчас мы рассматриваем использование в качестве SQL-сервера ORACLE , AS/400 и SYBASE. Именно здесь (как мы ожидаем) проявится правильность нашего подхода: при изменении инструмента (библиотеки связи с SQL-сервером - SOURCE) все наши приложения продолжат выполняться на новом сервере (к сожалению, придется также корректировать и SQL). Нужно сказать, что одноплатформенность не так уж и страшна. Специфика нашего времени заключается в том, что системы устанавливаются комплексно - от сетевого оборудования до прикладного ПО. Мы используем в БД формат файлов данных BTRIEVE, который поддерживают все ведущие SQL-серверы. Поэтому даже при смене сервера используемые данные не потеряются, а за время работы на дешевом ПО пользователи научатся работать в сложных распределенных БД.
Выводы
Мы не разрабатывали инструмент ради инструмента. SQL-Граф - это ответ на трудности построения приложений в архитектуре К/С. Приложение, разработанное в этой архитектуре - это объединение нескольких программ над единой БД. Это реальное время обработки, критичность к сбоям или неверной работе отдельного приложения. Более того, при построении заказных систем (а именно такой системой является БОСС-1) за все ошибки - и инструмента разработки, и SQL-сервера - отвечает разработчик. Это заставляет предъявлять повышенные требования к надежности инструмента разработки (даже в ущерб его быстродействию и сложности). Если при разработке одиночных приложений об инструменте разработки чаще всего спрашивают ради простого любопытства, то здесь ситуация абсолютно другая.
Инструмент в архитектуре К/С - это программное обеспечение промежуточного слоя между БД (SQL-сервером) и прикладной программой. Насколько прост он в освоении, насколько и надежен - именно это определяет жизнеспособность разработанного на нем ПО. Именно цикл сопровождения выходит на передний план в подобного рода системах. Такие системы строятся надолго, они могут видоизменяться, но, как правило, это опять-таки связано с новыми возможностями инструмента разработки. Смена SQL-сервера - это тоже прерогатива инструмента: именно он определяет объем необходимой переделки уже работающего ПО.
Все это мы попытались решить в нашем инструменте, вынеся на первый план именно этап сопровождения. Работоспособность инструмента была доказана внедрением ряда крупных проектов, которые и составляют систему БОСС-1. Опыт создания собственного инструмента позволяет нашим программистам легко осваивать новые инструменты, более профессионально разрабатывать приложения.
Три года назад на нашем рынке из инструментов, позволяющих строить DOS приложения, был представлен только JAM. Нас не устроил его интерфейс. Сейчас на рынке выбор богаче (в частности, MAGIC фирмы Magic).
Сейчас многие инструменты разработчика строят аналогично - таблицы БД, хранящие информацию о приложениях, обычно называют репозитарием. Если же используется хранение этой информации в файлах операционной системы, то необходимо решать проблему согласованности версий, и не совсем понятно, зачем использовать файловую систему при наличии СУБД?
Надо отметить, что отказ от файловой системы позволяет выполнять разработанные приложения и под NetWare Runtime, что еще более удешевляет систему и повышает ее защищенность от несанкционированного доступа в сеть (на рабочей станции ничего, кроме нашего приложения, не может выполняться - никаких "игрушек", а значит, и "случайных" вирусов, да и персонал занят только работой) и удобство работы - требуется только регистрация в СУБД, а не в сети.