Кубики и конструктор. Попытка реализации

| рубрика: Проектирование | автор: chief_editor
Метки:

От редактора. Статья является объединением нескольких писем автора (А. Скрыпника) в конференцию fido7.su.oop. В ней описана реализация ядра информационной системы, основанная на принципах "кубиков" и моделирующей графической среды. Кроме технологической конкретики сделана попытка раскрыть архитектуру построения подобных систем.

Пролог

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

Решил написать только потому, что изложенное по поводу конструктора и кубиков , а еще больше понятие СРЕДЫ разработки (в терминологии Усова), очень мне близко и созвучно. Попробую расказать о своем и коллег опыте при создании ядра разработки клиент-серверных сиcтем - АРДЕH.

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

У нас это желание появилось, когда мы начали в команде работать с разработкой сложных клиент-серверных систем - одновременно создавали ГИС (граф. информ. система)и автоматизировали одно крупное мед. учреждение. При всей непохожести задач они с точки зрения проектирования имели много общего - необходимо было очень серьезно работать с Сиквел СУБД, очень сложная объектная иерархия и гетерогенная среда разработки - Дельфи фронтенд с его объектностью и визуальностью и БД с их необъектностью и необходимостью совсем других подходов. Возникло желание иметь единую ОБЪЕКТHО-КОМПОHЕHHТHУЮ среду разработки, которая бы позволила с рел. СУБД работать на объектном уровне и позволяла бы гибко настраивать конечную программу для нужд пользователей - своеобразный конструктор ЛЕГО (на что я и купился когда началась дискуссия) на котором можно было бы делать программы - среды.

Сразу хочу ответить на на главный вопрос - Зачем и когда это надо?

Ответ простой - это необходимо когда система очень сложна и необходима гибкая настройка как под конкретного пользователя так и под бурно меняющуюся жизнь. В терминах подобных систем - нам гораздо ближе подход 1С чем Галактики с точки зрения подхода к проектированию. Hу не возможно для налоговой написать программу, для хранения сотен тысяч юр. лиц которая бы жила больше полгода в стандартных технологиях при нашем законодательстве - ты постоянно находишься в режиме переделок - гораздо проще отдать им конструктор, который бы настраивался под их нужды,(ТОЛЬКО один гибкий редактор отчетов не спас бы отцов украинской демократии) - меняется и формы и наполнение.

Теперь об самом главном - об ахиллесовой пяте подобных систем (что абсолютно правильно отмечали в дискуссии по кубиках и А. Кравченко и другие) - невозможность предусмотреть все кубики на любой случай жизни. То есть когда имеется среда, то очень тяжело выйти за ее рамки при возникновении новой проблемы, когда в рамках старой технологии невозможно решить новую. Ответ понятен - необходимо расширяемая среда с возможность дописывания того чего необходимо, а точнее чтобы поставить все в правильное положение - необходима библиотека классов, которая для решения стандартных задач имела возможность использовать среду разработчика и администратора системы.

Часть 1

Получив несколько писем о желании познакомиться с тем, что мы делаем я решил попробовать опубликовать часть информации о системе Арден. При этом я хотел бы отметить следующее и подчеркнуть - все ниже и далее изложенное - чистое IMHO. Просьба воспринимать это как "творчество молодежи" и своеобразный опус.

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

И последнее. Почему в этой эхе? Причина проста - наверное это одна из немногих эх, без засилья ламеров. Наверное имело бы смысл, опубликовать ее в Ru.delphi.db + Su.dbms.SQL, но я просто вижу, что те люди которых я безмерно уважаю читают и эту эху. Публикации вряд ли будут более частыми чем раз в неделю. При первой же просьбе от модератора или комодераторов будет прекращена.

Вводные положения

В данном разделе все понятия вводятся по возможности \<по нарастающей>, но иногда не удается избежать ситуаций, когда для полного понимания секции необходимо прочитать раздел до конца и вернуться назад.

Кроме того, необходимо учитывать фактор времени - некоторые вещи появились намного позже других; некоторые устарели; некоторые продолжают использоваться, хотя, если бы проектировались сейчас, были бы сделаны иначе. Например, система не была изначально спроектирована для работы в инфраструктуре COM (из-за отсутствия на начальном этапе полноценных средств разработки). Большое влияние на разработчиков имело знакомство в свое время со спецификациями CORBA 2.0 и CORBA-services.

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

В документе не вводятся детальные понятия объекта, временных и постоянных объектов, объектной модели, системы, интерфейса, литеральных и объектных типов данных. Вследствие этого документ получается как бы "не с начала". Но описываемой системе в некоторой мере присуща саморекурсивность, обычная для метасистем.

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

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

Начальные Определения и понятия

ARDEN - программная система для создания клиент серверных задач на базе Delphi, которая представляет надстройку над Delphi для создания уровня разработки, архитектуры задачи и администрирования разрабатываемых программных систем.

Пользователь - пользователь автоматизированного рабочего места (АРМ), созданного на ARDEN. АРМ настраивается как на группы пользователей (по функциональным возможностям) так и на конкретного пользователя (имя, пароль, протоколирование действий).

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

Программист - группа разработчиков, которые создают интерфейсы и подсистемы и настраивают ARDEN под конкретную предметную область применения.

Интерфейс - список методов и атрибутов, которые используются клиентом для изменения состояния объекта. (Hапример - выполнить, дать список параметров, получить данные)

Объект - понятия системы ARDEN, которое можно уникально определить в данной информационной системе. Объекты в ARDEN достаточно похожи на объекты СОМ, основного, но не единственного источника интерфейса. (Например - папка, таблица, отчет)

Сервис - интерфейс общего пользования, который имеется в одном экземпляре и используется всеми клиентами. (Например - типы данных, транзакции нотификации)

Подсистема - достаточно широка понятие, которое имеет в виду реализацию конкретной задачи, интерфейса, сервиса или фабрики класса. (Например - подсистема построения типа данных в базы, подсистема больших бинарных объектов, которые хранятся в файлах)

Фабрика класса - интерфейс, для создания объектов. Менеджеры классы, которые помогают выполнению некоторых конкретных действий системы. (Например, TreportStyleMgr - менеджер для установки стиля отчетов).

Протокол - правила использование данного интерфейса. (Например - для транзакций сначала выполняется StartTransaction, позднее Commit или Rollback, но не наоборот)

Уровень инфраструктуры системы

Временные (transient) объекты. Взаимодействие с объектом осуществляется исключительно через один из его (то есть, поддерживаемый им) интерфейсов. Получить интерфейс объекта (или \<временную ссылку на объект>) можно разными способами. Для того чтобы взаимодействовать с объектом, последний должен находиться в \<загруженном состоянии>, т. е. на него должна существовать объектная ссылка.

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

Т.к. сохранить временную ссылку на объект нельзя, для этого используются т.н. \<постоянные ссылки>. Объект-клиент может сохранить постоянную ссылку на объект-сервер, и для обращения к нему во время сеанса \<превратить> постоянную ссылку во временную.

Формат постоянной ссылки может быть произвольным, то таким, чтобы уникально идентифицировать объект. Кроме того, должен быть механизм превращения этой постоянной ссылки во временную (или \<загрузки объекта>).

Реестр постоянных объектов

Основным поддерживаемым форматом постоянных ссылок является т.н. . Он происходит исторически от структуры записей, т.н. алиасов. Алиасы изначально проектировались на уровне \<ниже> объектной модели, но теперь вместо слова \<алиас> можно ставить, в большинстве случаев \<объект>. Алиас предоставляет минимальный сервисный набор средств для хранения постоянных объектов. Алиасы хранятся в \<Таблице алиасов>. Алиас состоит из следующих полей:

  1. Идентификатор (ObjectID) - целое число, уникальное в таблице. Именно оно используется для идентификации
  2. Владелец (OwnerID) - используется для организации алиасов в дерево
  3. Полное имя (FullName) - строка, хранящая "имя алиаса для пользователя", т. е. в локализированном варианте, с пробелами и пр., никак не используется для идентификации
  4. Краткое имя (ShortName) - логическое имя алиаса; уникально для одного владельца. В некоторых случаях используется для связывания (нахождения) объектов по именам
  5. Физическое имя (PhName) - может использоваться разными реализациями объектов по усмотрению. Например, SQL-объекты хранят здесь свои имена
  6. Класс (ClassID) - указывает на алиас, соответствующий классу ("первичной реализации", об этом далее) объекта
  7. Тип алиаса (AType) - указывает на алиас, представляющий "тип алиаса" - по некоторой классификации. Некоторые типы алиасов жестко вшиты в соответствующие подсистемы
  8. Тэг (Tag) - целое число, может использоваться объектом по усмотрению
  9. Версия (Version) - используется для хранения версии реализации (класса, формата записи) объекта
  10. Версия объекта (ObjVersion) - версия конкретного состояния объекта. Объект-клиент может сохранять вместе со ссылкой и версию объекта. Если сохраненная и актуальная версии не совпадают, значит состояние объекта-сервера изменилось, и клиенту необходимо предпринять некоторые действия (например, сбросить кеш)
  11. Уникальный идентификатор (ObjUID) - GUID, уникальный идентификатор объекта. Планируется, во-первых, использовать именно его для идентификации объектов, во-вторых, при реализации экстранализации/интернализации, т. е. переноса прикладных макрокомпонент между системами
  12. Время создания/модификации, пользователь

Имеется некоторое количество жестко определенных констант-ID. Все ID больше нуля. Пользовательские ID начинаются с 1000.

Записываемые (streamable) объекты

Здесь и далее постоянными будем называть объекты, которыми соответствует некоторый алиас и на которые можно идентифицировать их постоянными ссылками. Имеется еще одна категория объектов, умеющих сохранять свое состояние - т. н. \<записываемые> (streamable) объекты. Работа с такими объектами производится по примерно такой схеме: постоянный объект не сохраняет ссылки на объекты (возможно, они не являются идентифицируемыми), а записывает в поток CLSID объекта и просит его записать свое состояние в тот же поток. При считывании из потока по CLSID находится фабрика, создается объект и ему предлагается считать свое состояние (о фабриках см. далее).

Сервисы

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

Классы

Каждый объект в классической модели является экземпляром класса. В первых реализациях понятие агрегата (контейнера) тоже отсутствовало, и каждый объект являлся экземпляром некоторого класса. Тем не менее, понятие класса осталось до сих пор, с более замысловатым названием \<первичная реализация>. Имеется множество объектов, функциональность которых практически не будет расширяться извне (при необходимости будет переписана/дописана первичная реализация). Для таких объектов понятие класса довольно удобно.

Класс (или, в контексте нашего описания, реализация объекта) регистрируется в таблице алиасов. Класс уникально идентифицируется своим CLSID (доступным через интерфейс IPersist). При создании постоянного объекта в поле алиаса ClassID прописывается ID класса. При загрузке объект по этому ID находит реализацию. Сейчас используется два метода получения реализации - по имени класса (устаревший) и по CLSID (современный). Детальнее описано далее.

Класс объекта рассматривается как равноправный объект, поэтому в описании в отдельности не рассматривается работа с объектами и с их классами. Понятия класс объекта используется потому, что:

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

Для построения больше сложных моделей объекта используется агрегатная (контейнерная) модель.

Фабрики

Фабрикой называется объект, создающий другие объекты. Принципиально различаются фабрики, создающие временные и постоянные объекты.

Результатом создания временного объекта является временная ссылка на запрашиваемый клиентом интерфейс созданного объекта. Так получаемые временные объекты чаще всего используются только объектом-клиентом, запросившим создание и живут короткое время. Сервисы же сохраняют состояние во время жизни системы, т.е. имеют возможность кэшировать данные, собирать статистику и ими пользуются \<много> клиентов.

Фабрики постоянных объектов создают новый алиас и возвращают его ID клиентом. Клиент передает полное и краткое имена и алиас-владелец. Класс и другие необходимые поля заполняет реализация фабрики.

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

Брокер

То, что подразумевается под брокером в данной системе, предоставляет более широкий сервис (не путать с понятием \<набор сервисов>), чем обычно, а именно:

  1. Работа с постоянными объектами: превращение постоянных ссылок во временные, регистрация классов
  2. Работа с сервисами: предоставление сервисов, регистрация и запуск
  3. Работа с фабриками: нахождение/получение фабрик, регистрация

Брокер доступен из любой точки кода через глобальную переменную.

Для загрузки объектов служит функция брокера CoLoadObject(ObjectID: TID): IUnknown. Загрузка объекта состоит из следующих шагов:

  1. проверяется валидность ObjectID
  2. из реестра считывается информация об объекте
  3. определяется класс объекта. Если класс явным образом не указан, создается объект, который обеспечивает базовое поведение
  4. определяется способ реализации класса: расширением базовой реализации или через фабрику класса
  5. проверяется доступность реализацию класса
  6. находится реализация класса по имени или фабрика по CLSID
  7. в случае фабрики созданный нею объект "обертывается" в экземпляр базового объекта для обеспечения базового поведения
  8. объект настраивается для обеспечения базового поведения
  9. на базе объекта создается агрегат (см. Агрегатная модель объекта)
  10. объекту сообщается о завершении инициализации и возможность выполнения COM-операций над ним
  11. клиенту возвращается IUnknown агрегата

Использование объекта с базовым поведением в качестве контролера агрегата обеспечивает стандартные сервисы для всех объектов и позволяет ожидать базовое поведение от объекта.

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

Запуск системы

Концепция модульности. Оформление реализаций. Агрегатная модель объекта

Классическая объектная модель работы с объектом формулируется в терминах сообщений: клиент посылает сообщение объекту, тот расшифровывает это сообщения. Традиционные реализации объектов в гибридных объектно-ориентированных языках программирования избегают этапа "расшифровывания". С течением времени эксплуатации количество сообщений, которые объект будет получать, может возрастать, а количество тех, которые объект сможет "расшифровать", остается постоянной.

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

Рассмотрим идеи, положенные в основу этой модели.

Интерфейсы объекта доступные через операцию QueryInterface. В простейшем случае эта операция имеет одну реализацию, проверяющую, поддерживает ли объект данный интерфейс и возвращающий его в этом случае. Таким образом, эта реализация предполагает, что ей известная структура объекта, то есть, известны все интерфейсы, которые объект поддерживает. Иногда поведение объекта легче моделировать, компонуя его с уже существующих реализаций - в результате объект представляется агрегатом, который, тем не менее, должен выступать целостным объектом COM.

Объект, отвечающий за экспонирование наружу интерфейсов своих частей, называется контейнером. Так как он "контролирует" поведение остальных, "внутренних" объектов, он еще называется контролером.

Общий (generic) контейнер отличается от специфицированного тем, что хранит список произвольных внутренних объектов и переадресовывает им запрос на обработку сообщения. Список внутренних объектов не является предопределенным, и это позволяет конструировать произвольные агрегаты.

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

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

Сам брокер не держит регистрационной информации о структуре конкретных настроенных агрегатов, но не запрещает провайдерам поддерживать такую информацию.

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

Архитектура \<клиент-сервис-провайдер>

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

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

Выполнение операции в первом случае выглядит так:

  1. имеем объект;
  2. брокер выделяет определенный сервис, который пригоден для выполнения операции;
  3. идентификатор объекта (или ссылка) передается сервису как параметр.

В объектоцентрической модели это выглядит так:

  1. имеем объект;
  2. просим у объекта интерфейс для выполнения данной операции;
  3. выполняем операцию над объектом

Оценим недостатки каждой из схем.

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

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

  • интерфейс объекта допускает выполнение данной операции, возможно непрямо;
  • выполнение операции гарантируется базовым поведением;
  • между сервисом и объектом есть внутренняя связь, которая обеспечивает выполнение операции.

В первых двух случаях объектоцентрическая модель подобна сервисоцентрической. Hо третий вариант абсолютно неприемлем для распределенных систем, когда реализации "разбросаны" по объектным системам. Требовать доступность определенного глобального сервиса в гетерогенной системе нельзя.

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

Простой пример. Пусть существует интерфейс, возвращающий описание объекта.

IGetDocumentation = interface
  function GetInfo: string;
end;

Пусть имеется сервис документирования, поддерживающий примитивное документирование - хранит определенный текст. Hо если определенный объект поддерживает документирование сам, - например, объект "схема отношений", документация о котором хранится в CASE-системе, поддерживает документирование лучше, чем общий сервис. Работа через объект дает доступ к этой, более широкой информации, а сервис может обеспечивать вариант такой функциональности для тех объектов, которые не поддерживают этого самостоятельно. При роботе через запрос просто не дойдет к объекту.

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

В системе присутствует определенная "главная" реализация сервиса, играющая роль "заглушки-коммутатора" и на основе определенной регистрационной информации предлагает клиенту одну из реализаций. Данный подход к проектированию сервисов обеспечивает масштабирование как "вверх", так и "вниз" (upsizing, downsizing).

Часть 2

В этом письме я попытаюсь изложить, то что у нас есть на сегодня (без учета перспективы) в АРДЕH. Арден - конструктор(ядро) на Дельфи 3.0, предназначенный для создания сложных клиент-серверных систем. Система многоуровневая.

Нижний уровень - Low Interface SQL Abstraction Layer Objects(САЛО) + Alias subsystem + suррort Object Relational maррing. Если коротко - САЛО - попытка избавится от SQL в системе и работать только с объектами - просто объектная оболочка. Ее главная задача дать возможность работать системе с разными серверами. То есть программист пишет запросы на объектах, а САЛО с учетом специфики синтаксиса каждого сервера транслирует в SQL - это обыкновенный заменитель SQL,правда на объектах. На сегодня поддерживается Interbase, Oracle 7.3, Informix (больше просто не приходилось делать, а вообще не проблема). Алиасы - хранилище метаинформации об всех объектах, которые хранятся в базе данных. Доступ к объектам идет с учетом трансляции имен в Алиасах, реализации моделей данных для использования в других подсистемах.

Второй уровень - Middle Interface Relational Objects + object requests broker. В рамках объектной модели СОМ реализовано подобие некоторых важных сервисов Корбы (Naming) для нормальной взаимодействия объектов-компонент в системе - без этого гибкую систему не сделаешь. То есть брокер запросов понимает как объекты системы могут взаимодействовать друг с другом. Более важное это возможность работать с объектным мапингом на реляционные базы данных. Реализовано наследование, поддержка сторед-процедур объектов, возможность работы из Дельфи через интерфес объекта данных, поддержка методов написанных на собственном макроязыке (КАВА) или на OQL - на языке объектных запросов.

Третий уровень - Software interface. Уровень разработчика системы тут уже появляются основные кубики-компоненты-объекты с которыми работает пользователь - разработчик. Главный - Project Studio - для работы с деревом объектов данных из таблиц и генерацией интерфейсов для работы с этими интерфейсами из Дельфи и генерацией IDL текста для порождения потом TLB системы. Конструкторское бюро - уже подход с точки зрения пользовательских объектов - то есть тут например для объекта можно задать методы отчеты и сразу же их отредактировать. Можно задать методы запросы меню, формы отображения. Конструкторское бюро может быть отдано в использование администратору системы. Часть объектов не работает с одной какой-то таблицей или объектом данных или работает с несколькими, для доступа к ним имеется полное дерево системы. Ну и конечно имеется большое кол-во реализованных кубиков, которые необходимы при разработке сложной системы - система данных с поддержкой округления, логирование, security, фильтры данных с учетом секурити, нотификации в системе и т.д. Разработчик имеет возможность работать с этими обектами из Дельфи и даже строя систему в которой гибкость не нужна получает массу полезных вещей. Проводя аналогию - это тот же подход Борландов с примером базы данных с рыбками, который строится мышкой, но только фенечек немного больше чем просто связывание по master-detail с отображением в гриде. При этом очень важно, что он может расширять систему для использования своих собственных объектов и встраивать их в дерево Арден.

Ну и четвертый уровень - это Users Interface. Объекты которые пользователь видит на экране и с которыми работает в базе данных. Hу тут целая куча кубиков:

  • DVO-data view object - таблица представления данных
  • ну очень навороченный грид с поиском, фильтрами (ест-но на сервере), стандартными отчетами, выделением цветом и маркерами по заданными пользователю условиями, редактированием в формах и т.д + целая подсистема для настройки индексов, представлений видимости полей
  • TVO - tree view object -все тоже самое но для дерева (склады, кадры, товары) с возможностью настройки окон гридов и дерева.
  • report-редактор отчетов с подключением OQL и работающий с объектно-реляционной иерархией + методы на каве.
  • form editor - редактор для форм, которые должны меняться. Обычно формы пишутся на Дельфи и собираются в проект статически так как тяжело всю логику вынести в редактор форм.
  • smart queries - хитрые выборки - построитель запросов на естественном языке. Очень навороченная система для того чтобы пользователь мог построить запрос к базе данных на близком к предметной области "родном языке". Отдельная тема - графический компонентный редактор, в качестве прикола на нем написано детское подобие Applicational Architect который малюет блок-схему проекта и тут же ее выполняет. Ранее был написан Data architect но руки не доходят до реализации всего, что нужно в нем - пока увы заброшен.
  • куча мелочи - меню эдитор, тулбары, tips of day и т.д.

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

Hа этом я сегодня пожалуй закончу. Если народ захочет - могу описать дальше и глубже (ну и ЕСЛИ модератор не погонит). Единственная проблема это проблема слона и философов - в данной эхе обсуждается наследование хобота от носа, в других колон-ног, но где обсуждать слона целиком? ;-) У меня есть желание рассказать о построении конкретной системы на примере (например? программы зарплаты) - со всеми объектами, таблицами, методами на Каве и технологии - но где? По Ардену у меня куча документации, но увы бОльшая часть ее на украинском языке (специфика Западной Украины), очень много ее будет на сервере в районе через месяц-второй.

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

Постскриптум (ответы на некоторые вопросы)

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

Сейчас когда например в контрагентах используется до пяти наследований, то во первых неясно как это малевать, во вторых на самом дереве объектной иерархии многие вещи достаточно подробно видны. Но я не считаю, что будучи наперед очень умными можно было бы это все спроектировать "правильно" и не переделывать. Многие технологии (поддержка интерфейсов в Дельфи, Корба и СОМ) просто отсутствовали или мы в них не разбирались. Другое дело, что необходима остановка и подведение черты под версиями и выпуск их как готового продукта (хотя бы для внутреннего использования ). И это очень важная проблема - когда остановиться.

А по написанию у меня очень сильная команда, причем "экспериментальным" путем установлено, что лучше использовать людей там где они круче всего себя чувствуют, хотя есть и "универсалы". За архитектуру ядра и написание особо сложных кусков отвечает два человека, один из них руководитель проекта по ядру, другой руководит также прикладным проектом по медицине. Некоторые очень сложные части они пишут на двоих - скажем поддержка объектов в реляционных базах писалась вдвоем на одной клаве - настолько там навороченный код. Есть разработчик "нижнего уровня" - за ним нюансы баз данных и всяческие объекты нижнего уровня разработки, которые не видны на верху - списки, сортировки, потоки и прочие "радости". Есть специалист по графике - он уже написал с десяток графических редакторов и отвечает за отчеты, 2Д и 3Д графику. Все что касается языковой поддержки - написания макроязыков, парсеров, скриптов, экспертов тоже пишет один программер. Ну и есть специалисты по интерфейсу и те кто пишет прикладные части. Полный цикл разработки, особенно в части тестирования увы организовать пока сложно - не хватает ресурсов. Особенно необходим спец по пользовательским интерфейсам и художник.

Если подытожить, то ядро пишет в среднем около 4 человек. Остальные меняются - скажем сейчас график пишет прикладную часть и т.д. В сумме ядро пишется 2,5 года.

Алексей Скрыпник (Alex Skrypnik), январь 1999 (с редакторскими правками, С.Тарасов, март 2008)

Архив дискуссии в fido7.su.oop