Все содержащиеся в программе основные объекты (clsTasks, clsProjects и clsToday) обращаются к локальной копии объекта-источника данных под именем clsData Provider. Это модуль класса VB, в котором поведение источника данных приравнено к значению vbDataSource. Объект clsDataProvider пользуется услугами посредника clsDataService, причем посреднические обязанности осуществляются через функцию под именем GetDataProviderRS, которая одним своим именем демонстрирует факт извлечения набора записей источника данных. Здесь же расположено большинство управляющих программой SQL-операторов. Наконец, приставка «Get» указывает на действие и в некоторой степени объясняет назначение процедуры. По-моему, я уже достаточно пожурил свою живность насчет нехватки комментариев, так что об этом недостатке я больше говорить не буду.
С точки зрения доступа к данным объект clsDataService является открытым интерфейсом логического звена данных. Объект clsDataProvider, описанный в предыдущем абзаце, обеспечивает взаимодействие между данными и уровнем графического пользовательского интерфейса. В составе clsDataService есть дочерний объект под именем clsDataAccess, который фактически осуществляет подключение к базе данных и исполняет передаваемые родительским объектом SQL-операторы. Подобного рода разделение обслуживания сводит взаимозависимость к минимуму и, по моему мнению, существенно облегчает сопровождение и модернизацию электронного администратора.
Другие достоинства и недостатки
По существу, я лишь мельком коснулся некоторых аспектов, которые можно было бы проверить на этом примере. Далее я затрону еще пару вопросов, которые могут вам пригодиться при проверке собственного кода.
Соединение с базой данных устанавливается в начале исполнения, поддерживается в активном состоянии и по мере необходимости передается нуждающимся в данных объектам. Эта схема вполне приемлема для двухзвенной программы с одним пользователем. В то же время, если мы попытаемся масштабировать мою программу для нескольких пользователей, окажется, что обозначенное проектное решение не слишком удачно. Причина, по которой я к нему обратился, заключается в том, что его можно было удобно и быстро реализовать. Оправдывают ли эти преимущества принятые решения? В принципе, мне этого хватает, поскольку расширять свою программу я не собираюсь. С другой стороны, это наглядный пример принятия под давлением временных ограничений простейшего решения, о котором впоследствии можно сильно пожалеть.
Динамические наборы записей открываются в каждом объекте по отдельности и, подобно соединению с базой данных, поддерживаются в активном состоянии. Такое решение повышает реактивность программы, если с ней на одной физической машине работает один пользователь, но сильно ухудшает шансы на масштабирование. Бессвязные наборы записей в данном случае могли бы существенно улучшить возможности масштабирования программы.
Нехватка связей между таблицами – это еще один очевидный недостаток кода, связанный с наборами записей. Иначе говоря, вместо того чтобы задать ссылку внешним ключом на таблицу проектов, я сохраняю имя проекта в таблице заданий. Таким образом, я полностью исключаю возможность переименования проектов.
Конечно, можно было бы подумать и над другими решениями, но то, на котором я остановился, по крайней мере, позволило оперативно генерировать для подведомственной мне группы еженедельные отчеты.
Нет. Поскольку мне хотелось сделать программу удобочитаемой, я в основном отдавал предпочтение закрытым и открытым перечислимым типам (перечислимые типы с глобальной областью действия присутствуют в basMain). Есть все же несколько массивов элементов управления, на которых вместо перечислимого типа установлена числовая ссылка. Но в основном, чтобы понять назначение параметра, достаточно взглянуть на его определение.
Заключение