Архитектор
25,3
рейтинг
15 октября 2012 в 22:18

Разработка → Динамическая интерпретация метамоделей

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

«Вот что я имею в виду под производящим произведением или, как я называл его в прошлый раз, «opera operans». В философии существует различение между «natura naturata» и «natura naturans» – порожденная природа и порождающая природа. По аналогии можно было бы образовать – «cultura culturata» и «cultura culturans». Скажем, роман «В поисках утраченного времени» строится не как произведение, а как «cultura culturans» или «opera operans». Это и есть то, что у греков называлось Логосом.»
// Мераб Мамардашвили «Лекции по античной философии»

Постановка задачи


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

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

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

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

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

Какие существуют сложности на пути повышения абстракции программных компонентов и структур данных:
1. Связывание по зашитым в программный код идентификаторам. Обращения к структурам данных и к программным интерфейсам осуществляются с помощью логических идентификаторов, которые преобразуются в конечном итоге в адреса вызовов, относительные адреса в оперативной памяти и сетевые вызовы. И при статическом (раннем) связывании и при динамическом (позднем) связывании, идентификаторы зашиты в программном коде компонентов системы, более того — разбросаны по коду. А для повышения абстракции код не должен содержать идентификаторов, указывающих на модель предметной области, а только идентификаторы, указывающие на метамодель.
2. Применение статической типизации переменных. Для задач с динамической предметной областью характерным является не только то, что мы заранее не знаем тип переменной (объекта, класса, выражения, константы, функции), но этот тип может быть даже неизвестен во время компиляции. Как минимум, язык программирования, подходящий для решения подобных задач должен поддерживать интроспекцию и динамическое создание типов, классов и переменных вновь созданных типов.
3. Смешивание в одних классах модели предметной области и решения системных задач. Например, класс «автомобиль» не должен знать ни какими визуальными контролами, библиотеками или тегами он выводится на экран, ни то, как ему нужно сериализироваться и с помощью каких синтаксических структур, как ему храниться на диске или в базе данных, как ему передаваться по сети, с помощью каких протоколов или форматов данных, или в каком виде он должен быть развернут в оперативной памяти.
Я не утверждаю, что приведенные техники программирования не имеют места, они вполне применимы и незаменимы для решения задач со статической моделью предметной области. А статическое и динамическое связывание подходит для разработки системных аспектов программного обеспечения с динамической предметной областью, но приведенные техники не должны быть связаны с обработкой модели или метамодели предметной области.

Динамическая интерпретация метамодели


Перед тем, как описать принцип динамической интерпретации, мы уточним, что мы будем понимать под используемыми терминами.

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

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

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

Схема компонента ИС с динамической интерпретацией. Сокращения в схеме: МС — машина состояний, К — конфигурация компонента, ПХ — постоянное хранилище, Л — логика. Вызовы из компонента идут к нижнему компоненту, а запросы идут от верхнего (ответы идут в обратном направлении).

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

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

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

Динамически построенные прикладные структуры данных и прикладные сценарии (события, методы обработки данных) опираются на вызовы API прикладной виртуальной машины, в которой запущена динамическая модель. Такое API, в свою очередь, «садится» на API среды запуска (например, на API операционной системы, мобильной операционной системы, виртуальной машины, API облачной инфраструктуры и т.д.). Динамическое построение модели происходит как в серверных, так и в клиентских (пользовательских) компонентах ИС, т.е. интерфейс пользователя строится динамически, а роль API тут выполняет используемая библиотека визуализации (компоненты GUI) или среда отрисовки «Renderer» (например: HTML5, Flash, SilverLight, Adobe AIR). Сетевые интерфейсы так же могут строиться динамически, однако, протоколы передачи и форматы обмена данными, конечно же, должны быть зафиксированы (вкомпилированы в компонент) или выбираемы из доступного набора, доступного на платформе (например JSON, XML, YAML, CLEAR, CSV, HTML, и т.д.).

Пользователь инициирует события в GUI, которые приводят к локальной обработке данных или сетевым вызовам. Смысл динамической интерпретации в сетевом взаимодействии заключается в том, что идентификаторы вызываемых удаленных процедур, их параметры и структура возвращаемых данных заранее не зашита в вызывающий компонент, а получаются из метаданных во время динамической интерпретации метамодели. Удаленная же сторона так же не имеет фиксированного интерфейса (заранее зашитых в откомпилированную компоненту методов, доступных через сетевые вызовы), вместо этого, заранее известен только метапротокол (форматы передачи данных, типы параметров, обработка которых поддерживается) и механизм интроспекции, позволяющий динамически считывать структуру удаленного сетевого интерфейса. Например, такой метапротокол можно создать из декларативных структур, объединив их с протоколами HTTP, JSONP, SSE, WebSockets и интерфейсом интроспекции.

Роль машины состояний в динамической интерпретации в том, чтобы сохранять сессию с необходимым набором данных как на клиенте, так и на сервере между сетевыми вызовами. Это необходимо для того, чтобы обеспечить последовательную или интерактивную человеко-машинную обработку данных, при которой действия пользователя приводят модель в определенное состояние, а каждый последующий сетевой вызов зависит от предыдущего в пределах транзакции. Кроме того, машина состояний позволяет существенно сократить расходы трафика и вычислительных ресурсов, кешируя метаданные, данные и даже саму динамически построенную модель в оперативной памяти. Реализация машины состояний возможна с помощью структур в оперативной памяти (для языков программирования), локального хранилищу («Local Storage» для HTML5 приложений) или сервера memcached (в основном для серверных компонентов).

Постоянное хранение данных в информационных системах с динамической интерпретацией возможно в СУБД: реляционных базах с параметрическим подходом к схемам данных или с применением интроспекции метаданных схемы хранения, базах данных класса ключ-значение («Key-value») или бессхемных хранилищах («Schemaless»). Стоит отметить, что бессхемные хранилища (например MongoDB) более естественные для систем с динамической интерпретацией, т.к. предусматривают динамическую типизацию и гибкое управление структурами (близкое к языкам программирования со слабой типизацией). Для реляционных СУБД применяется следующий подход: кроме основных таблиц, хранящих модель предметной области, в БД помещаются дополнительные таблицы для хранения метаданных, и эти таблицы содержат дополненную информацию о структуре основных таблиц (расширенные типы данных, параметрах обработки, дополненную классификацию связей и императивные сценарии).

Выводы


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

Дополнительные материалы


1. Метапрограммирование
2. Применение метамодели при проектировании баз данных с несколькими абстрактными слоями:
Часть 1 и Часть 2
3. Интеграция информационных систем
Timur Shemsedinov @MarcusAurelius
карма
161,5
рейтинг 25,3
Архитектор
Реклама помогает поддерживать и развивать наши сервисы

Подробнее
Реклама

Самое читаемое Разработка

Комментарии (46)

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

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

    Для задач с динамической предметной областью характерным является не только то, что мы заранее не знаем тип переменной (объекта, класса, выражения, константы, функции), но этот тип может быть даже неизвестен во время компиляции

    Ну, наверное не компиляции, а начала интерпретации? И откуда появилась такая уверенная характерность? Имел опыт работы со статической строгой типизацией при проектировании метамодели (~бизнес логика, метаданные — описание типов и данных, императивное описание алгоритмов их обработки) и все было отлично.

    но для ее динамической интерпретации, т.е. для преобразования ее в модель предметной области

    Вот тут очень хочется увидеть детальный пример. Каким образом вы из абстрактной логики, посредством метаданных, формируете конкретные бизнес-логики? Каким образом вы формируете абстрактные логики, чтобы их можно было преобразовывать к конкретным бизнес логикам? Я так понимаю это и есть суть статьи, но вы об этом ничего не сказали…

    — Я так и не понял, что конкретно вы описывали. Если формальную модель метамодели, то почему нет классификации, зачем вы обязали присутствие машины состояний? Если конкретную систему, то почему не указана что это за система?

    P. S. Метапрограммирование — градиент развития определенного класса задач программирования, я вам благодарен за то, что вы освещаете эту тему.
    • +3
      Я старался не привязать статью ни коим образом к разработкам моей компании и нашего НИИ, изложить теорию в чистом виде, даже без ссылок на реализации на конкретных языках, библиотеках, продуктах и технологиях. У нас на этом работаю коммерческие продукты, а Хабр не место для рекламы, а в исходном коде я не все могу выложить, но кое-что выложу, когда мы причешем это к состоянию, достойному для примера.

      Действительно, ни какой магии нет, более того, можно привести несколько общеизвестных систем (и даже классов систем), построенных на интерпретации метамоделей, хоть мы и не рассматриваем их как типичный пример, т.к. это не прикладные системы, а системы общего пользования, но для примера они очень показательны. Веб-рбаузеры — это типичные специализированные виртуальные машины, DOM — это метамодель страницы, а страница приходит сразу с данными и метаданными (данные — это теги и контент, а метаданные — пользовательские атрибуты тегов и скрипты по их обработке). Еще примеры: электронные таблицы (в частности Excel), Matcad, другие CAD системы, снабженные внутренними интерпретаторами сценариев и широкого набора метаданных.
      • +1
        Программисты, которые пишут код на html + js, привязываются к бизнес-логике, а вы говорили о повышении уровня абстракции. Меня интересует конкретно этот аспект. Какими уровнями абстракции оперируют (аналитики?) вашего НИИ при разработке коммерческих продуктов, и каким образом вам удается использовать повторно метаданные и целый подсистемы.
        • +2
          Программисты, разрабатывающие веб-браузер не привязываются к бизнес-логике, как и программисты разрабатывающие Excel и Matcad. Эти продукты являются мета-продуктами, превращающимися в решение для конкретной задачи только в рантайме. Но все, чего я добиваюсь подобными статьями, это признания метапрограммирования дисциплиной в рамках специальности «Программная инженерия», чтобы это воспринималось как научная дисциплина, преподавалось в ВУЗах (по крайней мере, моем — КПИ), этим и обусловлен «книжный» стиль изложения, завтра же статью получат наши профессора для рассмотрения. Ну а программистам тоже полезно подниматься на подобный уровень рассмотрения. Конечно эту дисциплину нужно снабдить практическим курсом, вплоть до лабораторных работ.
          Какими уровнями абстракции оперируют (аналитики?) вашего НИИ при разработке коммерческих продуктов, и каким образом вам удается использовать повторно метаданные и целый подсистемы.

          Например, если нужно сделать систему по «учету рабочего времени разработчиков ПО», то повышением уровня абстракции будет система по «учету времени» и можно построить соответствующую метамодель, а еще повысив абстрактность получится система по «учету ресурсов» (время как частный случай ресурса). При этом, систему для «учета ресурсов» написать в 2-3 раза сложнее, но из нее можно сделать 20-30 систем, по учету разных типов ресурсов или выпустить ее как продукт, в котором пользователь сам задаст параметры учитываемых ресурсов. А такую систему сделать в 5-10 раз сложнее, но из нее пользователи сделают 5-10 тысяч систем и будут арендовать это решение по принципу SaaS.
          • 0
            Похоже что пример с браузерами не является удачным, поскольку программисты и самих браузеров и программисты html+js используют классическую подход — построение модели предметной области? И браузер не превращается в решения конкретных задач в рантайме, а исполняет конкретные задачи в рантайме. А иначе, чем Java машина хуже, gcc? Сейчас буду перечитывать статью в контексте поиска формальных границ.

            Пример с учетом ресурсов — хороший, спасибо, понял).

            В родном КПИ преподают Microsoft Access и MFC :(.
            • +2
              Программисты браузеров как раз не строят модель предметной области и браузеры уже давно превратились в виртуальные машины, не содержащие решения конкретных задач, а лишь очень абстрактных. Например, в браузере нет средства для отрисовки графиков посещаемости веб-ресурса, но есть Canvas, на котором можно можно сделать вывод любых графиков, в том числе и посещаемости ресурса. Можно решить эту задачу иначе, есть SVG, а простые графики можно отрендерить вообще тегами. В любом случае, Canvas, SVG и теги являются метамоделью для графиков посещения ресурсов.

              Java, как и .NET — это виртуальные машины, исполняющие откомпилированный код, в них не обязательно происходит интерпретация метамодели в рантайме. Можно писать классически, а можно динамически, технология не предрасположена к способу. Метамодель и обработку метаданных можно частично реализовать хоть на bat-файлах или на юниксовых шел-скриптах. Например, у моего коллеги есть шел-скрипты для развертывания БД с динамическим формированием SQL-скриптов из шаблонов и метаданных. Но естественнее эти подходы работают на языках с динамической типизацией, а на C# вот теперь можно использовать dynamic. Вообще, мне бы ассоциативного массива хватило плюс эвалуации кода из строковой переменной, но многим это покажется не серьезным, не концептуальным :)
              • 0
                Программисты браузеров, при программировании браузеров строят вполне конкретный модели и решают очень конкретные задачи:
                1. Рендеринг текста.
                2. Общение по HTTP
                3. Автозагрузка страниц…

                Я это имел ввиду.

                Из статьи я понял, что сanvas можно считать метамоделью тогда и только тогда, когда html+js можно считать метаданными. Правильно понимаю?
                А html+js — метаданные потому, что декларативный + императивный характер и выполняются в виртуальной машине? Но ведь в виртуальной машине, а не прикладной виртуальной машине…
                Уточните пожалуйста разницу между прикладными задачами и системными.
                • +2
                  Ну вот с браузером, как с примером, я согласен, есть проблема — это системная задача, а не прикладная. А все средства HTML5 являются и моделью и метамоделью одновременно. Как Вы и сказали, при наличии HTML+JS, да еще + динамических запросов, возвращают JSON — конечно эти компоненты браузера работают как метамодель. Но браузер при этом не становится прикладной виртуальной машиной, а скорее операционной системой, а вот прикладной виртуальной машиной можно считать часть JS скриптов. Это запутанный пример, хоть он и лежит на виду, но я его приводить не люблю.
          • 0
            А как быть с проблемой избыточного функционала? Адаптация такой системы может быть сравнима по затрачиваемым усилиям разработке системы с нуля только под заданные нужды.

            На определенном этапе абстрагирования ваша система вырождается из прикладной в систему разработки приложений. Думаю, с этого собственно и стоило начинать.
            • 0
              Это смотря как пользоваться, на практике, нам это позволяет, например, сгенерировать интерфейсы для 100 таблиц за 5 часов или понизить трудоемкость разработки интерактивной анимации в 80 раз (это не не шутка, мы на примере считали по затраченному времени). Наша задача — понизить необходимый уровень специалиста по адаптации с программиста или архитектора, до пользователя или эксперта предметной области. Но конечно, любая идея, доведенная до экстремизма — страшна.
      • +1
        Вот такие примеры, как веб браузеры, (а вместе с ними — СУБД, и другие подобные решения, реализующие метамодели) очень надо включить непосредственно в статью. По опыту, человеку, далекому от понятия метамодели, объяснить что это такое и зачем нужно почти невозможно без живых, понятных ему примеров. В результате получается, что статья реально доступна только тем, кто уже и так понимает что такое метаподход. А для этой аудитории, честно говоря, ничего интересного не прозвучало :-(.
        • 0
          Так браузер не особо хорош, как пример, он понятен сходу, ведь принцип тот же, но когда начинаешь его копать то оказывается, что «сanvas можно считать метамоделью тогда и только тогда, когда html+js можно считать метаданными», как резонно заметил TheHorse. Тут нужно примеры, как пример с учетом ресурсов. Я наберу хороших примеров, это же как-то нужно еще студентам пояснить, а не только инженерам-программистам.
          • +1
            Тогда (из своего опыта) рекомендую включить в примеры задачи управления документами вообще и документооборота в частности (которые в статье почему-то упомянуты как не нуждающиеся в метамодели). Я много лет занимался вопросами как раз обобщенных решений для работы с документами, так что могу с уверенностью утверждать, что описываемый Вами подход в этих задачах вполне применим.
            • 0
              И даже напрашиваются…
  • 0
    Если я правильно понял, то 1С: Предприятие работает по такому же принципу. Если так, то вопрос: в чём принципиально новое именно в вашем подходе?
    • +1
      Я не претендую на создание принципа, он существовал, кстати, и до 1С. Более того, не существует таких программных систем, в которых не применялись бы элементы метапрограммирования. Я лишь применяю к этому принципу научный подход, исследую, осмысляю и описываю. В этом принципиальное отличие науки от техники, которая создает, но не принципы, а их реализации, внедрения. Архимед не создавал закона Архимеда, он его сформулировал, а тела погруженные в жидкость выталкивались и до него.
      • +1
        Тогда, пожалуйста, побольше практических примеров, потому что с точки зрения теории метапрограммирование — это то же самое программирование, только задача чуть покрупнее.
  • +1
    Разработка метамодели для последующего обощения функционала требует гораздо большего времени и анализа, чем собственно реализация бизнес логики. а бизнес, который платит деньги, требует, чтобы было готово «вчера», в лучшем случае — «завтра». Поэтому в своих проектах мне практически не удается выделить и использовать метаданные. Когда приходит понимание, что можно было обобщить и какие метаданные были бы полезны — проект уже закрыт, а впереди новый.

    но тема очень интересная, жду продолжения :)
    • +1
      monzdrpower,
      вы совершенно верно указали на финансовую составляющую этого подхода. Если клиент клиент готов к спонсированию подобного подхода — он получает и все плюшки. Если вы (или ваша компания) вкладываетесь в построение метамодели для определенного вида задач, то продавать решения на основе этой модели можно гораздо выгоднее (и/или быть более конкурентоспособным, предлагая реализацию быстрее/дешевле чем конкуренты). В этот момент мы подходим к известным понятиям рынка — оценке рисков и выбору области для инвестирования.
      На мой взгляд, именно подобные подходы на основе мета-программирования и позволяют решать серьезные бизнес-задачи на разумное «на вчера».
      • +1
        ага, а еще эти методы позволяют аргументировано и безрезультатно проедать бюджет в течение весьма длительного времени. Потому как для того чтобы команда успешно реализовала метамодель, пригодную для практического применения, сначала нужно лет несколько успешно порешать практические задачи на прикладном уровне. А без этого почему-то получается очередной многофункциональный, очень полезный, но неповоротливый комбайн, который никто не понимает как использовать в конкретной задаче. :-(
        • 0
          Пример — Hibernate :-) Сообщество его уже довольно долго пилит, и до сих пор в сложных случаях оно не работает.
          Хотя есть и удачные примеры, типа SQL, но это уже полноценный DSL, без хаков.
          • +1
            Есть такая поговорка, что классный бильярдист не делает сложных ударов. Все его удары довольно простые. Но конечно тут есть определенная доля лукавства, потому что, чтобы следующий удар был простой — нужен хороший «выход битка» после предыдущего удара. В этом собственно и заключается сложность бильярда, не в «кладке», а в «выходе» и построении серии.
            Так и в программировании — джедаем нужно быть не для того, чтобы «решать сложные случаи», а для того, чтобы предвидеть и избегать их, выбирая простые и эффективные способы решения задач.

            Это был псто в защиту Хибернейта :)
    • +1
      Я часто чувствую, что буксую, до тех пор, пока не выделю из модели мета-модель.
      Как правило, именно после этого становится очевидным выбор адекватных задаче инструментов, часто уже существующих в виде кода или (если на пути встает юридический отдел) методик.
      К каким-то запредельным накладным расходам (в разработке ли, в исполнении ли) это не ведет, если не быть догматиком и вволю экспериментировать на стадии прототипирования («Clean code» и палитра рефакторингов в помощь).
    • 0
      Видимо, у Вас мелкий или средний бизнес.
      В крупном бизнесе, как правило, выделяют инвестиции на анализ и обобщение подходов.
      • 0
        Мы делали документооборот для сети гипермаркетов с филиалами по всей стране. Ни на какой анализ время никто не выделял, экономили на всем, велено было сделать на опен-сорс продуктах за полгода, ибо «в апреле начало годовой договорной кампании». Сделали к маю.
        Им не нужно открывать исследовательскую лабораторию, им деньги надо зарабатывать.
        • 0
          Это чистый прощелк руководителя или ориентация на быстрый возврат инвестиций. Любые архитектурные подходы дают результат только после нескольких лет применения и внедрения, а научные исследования после 8-10 лет, у нас бизнес для этого очень нетерпелив.
  • +1
    Почему для задач, где количество классов обрабатываемых объектов сравнимо с количеством их экземпляров, необходимо использовать принципиально другой подход?

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

    2. Уже говорил, что динамическая типизация и интроспекция — не обязательны. Обязательным считаю динамическое определения формата, но не типа.

    3. Смешивание предметной области и системных задач в одном классе — просто низкокачественный код, и является сложностью для любых модификаций.

    Я бы, как главную сложность повышения уровня абстракции, назвал бы построение метамодели, которую можно было бы минимальными усилиями использовать в различных моделях предметных областей.
    • +2
      Почему для задач, где количество классов обрабатываемых объектов сравнимо с количеством их экземпляров, необходимо использовать принципиально другой подход?

      По той же причине, что и для слабо-структурированных, слабо-формализуемых задач проще использовать бессхемные хранилища (например, MongoDB), чем реляционные СУБД. Представьте, что Вам нужно сделать 10.000 классов при 50.000 экземпляров — это же неподъемная задача, нужно строить такие уровни абстракции, при которых эти же 50.000 экземпляров смогут уложиться в 50 классов. Конечно, я оперирую пока не четкими метриками (одного порядка, много, мало...), но можно найти тут более четки границы, описывающие оптимальное количественное соотношение.
      Связывание по зашитым в программный код идентификаторам — неизбежно, и будет присутствовать и в виртуальной машине и в коде метамоделей.

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

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

      Но, извиняюсь, это же сплошь и рядом, «Мы окружены шпаной» © проф. Пятигорский. И при таком смешивании уровней абстракции невозможно подняться до метамодели, если хоть одним статическим связыванием модель привязана к более низкому уровню абстракции, вся работа — насмарку.
      Я бы, как главную сложность повышения уровня абстракции, назвал бы построение метамодели, которую можно было бы минимальными усилиями использовать в различных моделях предметных областей.

      Согласен, но это уже искусство и дар программиста, работающего над метамоделью. Я лишь стараюсь оторвать программиста от рутинного кода и дать ему обзор методов, с помощью которых можно поднять эффективность, повторное использование и гибкость.
  • +1
    Интересно, что я натолкнулся на Хабре на такую статью. Я как раз сейчас интересуюсь такими вопросами, меня постепенно подгоняли мои предыдущие проекты к этому, а теперь ещё MPS в руки попал :)
    После прочтения статьи меня интересует вопрос — а какими инструментами вы разрабатываете метамодель и метаданные? Для меня сейчас отсутствие IDE для этого всего является проблемой, так как по сути мы создаем свой язык, и программисту приходится соблюдать его, а не только фактический формат, в котором описаны метаданные.
    • 0
      Если в eclipse мире, то www.eclipse.org/Xtext/
    • 0
      Это не простой вопрос, и если для разработки метамодели подходят все те же инструменты, что и для статической модели, то вот для метаданных в большинстве случаев, ни какие распространенные IDE не могут быть применены и нужно разрабатывать свою IDE или хоть какой-то простой редактор. Метаданные нуждаются в валидации и отладке, в диагностике ошибок и тут работы много. Но самый смешной и радостный момент у меня был, когда я сделал такой редактор для метаданных универсально редактора баз данных и получил на выходе уже динамически интерпретированный такой же редактор, но гораздо удобнее ) с того времени, часто редактирую метаданные в IDE, созданном на метаданных же.

      О языках и технологиях: в разное время мы использовали разные платформы (Clipper, Delphi, C#, PHP, NodeJS) и разные СУБД (dBase, Informix, Interbase, MsSQL, Oracle, MySQL, MongoDB), но подход с динамической интерпретацией реализовывали с вариациями везде. Постепенно понимание развивалось и сейчас меняется. Есть надежды, что окончательно переведя все наработки на JS, мы перестанем быть зависимы от платформы, контролируемой корпорациями (Borland, Microsoft, Oracle, Apple) мы перейдем на зависимость от стандартов (IETF, W3C), это гораздо приятнее. А на JS с его широкими динамическими возможностями мы уже покрыли всю клиентскую и большую большую часть серверной части. И я тут даже не столько о веб-приложениях, как о том, что JS имеет множество реализаций и мы можем встроить интерпретатор JS или даже полноценную виртуальную машину V8 в свой продут на любом языке. А в Windows 8, кстати, JS является одним из основных языков разработки оконных приложений на ряду с C#. В новом маркете Win8, кстати уже есть наше приложение, полностью построенное на динамической интерпретации метамодели (статью про него, кстати еще весной, сразу после публикации в маркете, мы выложили на Хабр, но администрация ее заблокировала, к сожалению).
      • 0
        Ещё один аспект — если не секрет, разработкой и поддержкой метаданных кто занимается? Ваш программист или администратор системы уже на стороне клиента?
        Изменение метаданных происходит отдельно от приложения или внутри самого приложения через специальный интерфейс?
        • 0
          В разных приложениях по-разному, есть с отдельным редактором, в который вводит метаданные специалист по предметной области (например юрист, вносит свои экспертные данные), в другой системе аниматор в своем специализированном IDE работает, а в Data-aware приложениях редактор встроенный, иногда сами пользователи вносят изменения в метаданные (они метамодели не меняют, только влияют на ее интерпретацию), могут добавлять поля, изменять типы и даже валидацию менять, выбирать визуальные контролы, устанавливать их поведение, но это все в рамках, ограниченных разработчиками. Систем, в которых метамодель сама разработана на динамическом языке, и происходит двойная динамическая интерпретация мы не еще не реализовывали, но пытаемся в экспериментальном режиме.
          • 0
            Как то все убер-круто выглядит. Не могу поверить, что все так гладко и красиво. И на веб уже перешли, и метаданные с редактором столько очевидны, что их менять кто угодно может (я не про валидацию и визуальщину, а про предметную область), и редактор для всего есть, и работает везде…
            • 0
              Ну проблем еще полно, но выглядит уже внушительно. Сами пользователи конечно правят мало и не все способны, но правят. А вообще, с этим классом систем постепенно выделяется отдельная ката суперпользователей, которые не программисты, но метаданные править могут и в голове предметную область держат. По поводу «на веб уже перешли»: в одном из проектов у нас сейчас к одному серверу подключаются интерфейсы разных языков, андроид-приложение на Java, веб-интерфейс, Windows Phone приложение на C#, и скоро будет iOS приложение на Objective C. Редактор оставляет желать лучшего, от него одна радость, что он сам себя редактирует )))
            • 0
              Я думаю, это следующий шаг в разработке ПО. Программы для клиентов уже есть — их делают программисты. Теперь облегчать труд программистам, и здесь, я думаю, ещё непаханный край)
              Святой грааль программирования — это программа, которая делает другие программы по команде оператора.
              • 0
                Динамическая интерпретация — это не искусственный интеллект и не аутопоэтические системы, программа сама себя не пишет, она только строит себя по шаблону. Мы не искореняем интеллектуальный труд инженера, мы искореняем копипаст и рутину.
                • 0
                  > мы искореняем копипаст и рутину

                  Путём абстрагирования. Но в итоге мы хотим автоматизировать разработку ПО настолько, насколько это возможно. Конечно, это не ИИ, это попытка приблизиться к тому, что ИИ мог бы дать нам.
          • 0
            А если метаданные изменились из внешней системы, у вас есть механизм контроля изменений для того, чтобы отобразить их на уже существующих схемах в БД?

            Мне кажется, что чем глубже копать в сторону метапрограммирования, тем глубже яма )
            • 0
              Не совсем понятно, что такое «из внешней системы», но при изменении метаданных из редактора, обычно даже перезапускать приложения не нужно, они постепенно по мере обращения берут новые метаданные, сравнивая их версии. Динамически менять структуру в реляционках не практикуем), а вот в бессхемных БД — это удобно.

              Ну чем глубже комать, тем яма глубже по определению ) Тут нужно останавливаться и закладывать фундамент где-то, прекращать процесс абстрагирования, иначе можно сделать абстрактную программу под названием «программа», которая делает все что угодно + кофе варит.
          • 0
            После введения двойной интерпретации у вас люди разделятся на две группы — первая будет работать на первом-втором уровнях, вторая — на втором-третьем. Причем доля вторых будет увеличиваться, а первых — уменьшаться.
            Аналогичное сейчас происходит в языках программирования — интерпретируемые языки начинают вытеснять компилируемые на бизнес-задачах, а в ассемблер и машинные коды уже никто не лезет, разве что в ассемблер виртуальной машины (но это все равно уже не машинный уровень, не так ли?)
            • +1
              И, естественно — примеров второго уровня метамодели людьми создано не очень много.
              И все идут из огромного объема практики в различных условиях.
              Ни один архитектор не способен проработать два мета-уровня абстракции.
              • 0
                Абсолютно согласен, это только итерационный процесс, эволюция системы. Поднятие уровня абстракции очень полезно для скорости разработки и переносимости кода (ту же бизнес-логику на js можно перенести из проекта в проект вместе в интерпретатором js, коих есть на выбор), для того, чтобы решение было кратким и описывалось в терминах предметной области. Но вот на производительность это влияет не лучшим образом, поэтому чрезвычайно важно регулярно пересматривать этот слоеный пирог и иногда выбрасывать слои из середины.
  • +2
    На практике, программные платформы, основынные на принципах интерпретации метамодели явлются тяжеловесными и страдают проблемами с производительностью. Исходя из опыта поддержки и расширения подобной системы могу утверждать что затраты на разработку весьма высоки, так как большенство технологий (имел опыт в основном с JEE) не применимы в данном контексте, так как они требуют наличия жестко заданной модели предметной области чаще всего в виде POJO. Как результат JPA, EJB, JAX-RS, JAX-WS, JAXB и т.п. — слабые помошники. Но зато сколько радости при проектированнии таких систем :)
    • 0
      Такая же вата у меня сейчас. Из-за этого и поглядываю на DSL + генераторы. Xtext обошел меня стороной, потому что сижу на идейке, но в MPS вижу очень большой потенциал.
      Касательно JPA — можно либо сгенерить POJO и методы с конкретными кейсами из предметки, либо сразу жахнуть JDBC.
      К сожалению, пока всё это только не на практике, а в проектах.
  • 0
    Внимание! Добавил в статью важную цитату из Мераба Мамардашвили про философский фундамент идеи. Если интересно, читайте Мераба (а лучше слушайте его знаменитые кассетные записи), у него ссылки на Пруста, на Декарта и на Гераклита. Так что, различие порожденной природы и порождающей, было известно давно и над этим задумывались.

Только зарегистрированные пользователи могут оставлять комментарии. Войдите, пожалуйста.