Что такое MDA — архитектура приложения управляемая моделью.


Что такое DDD — разработка приложений на основе правил предметной области.


Как часто при рарзработке информационных систем нам (архитекторам, программистам) приходится упрощать видение предметной области, чтобы закончить проект в какие-то приемлемые сроки.
в 1998 году группа ребят из Швеции решили сделать что-то интересное. Buisines Object Layer for Delphi BOLD, инструмент который позволил бы имея модель описания предметной области разработать в приемлимые сроки приложение, насколько я помню DDD еще не пахло. Задач стояло много, но одна из задачь уйти от SQL. в качестве языка запросов использовать OCL -object colnstraints language язык ограничений. вот в 2002 году Борланд купила эту компанию, и начала разработку продукта Enterprise Core Objects. К тому времени они успели выпустить ECO 1, который по функциональности даже рядом не стоял в решением BOLD для Delphi. короче история длинная… что мы имеем сейчас:
ECO 5 самый мощный инструмент для разработки приложений по DDD и MDA, который просто НЕ ИМЕЕТ аналогов:
язык запросов OCL, эволюцию базы данных, транзакции, блоки отката, синхронизация нескольких объектных пространств (причем передаются не все объекты а только изменения), подписка на объекты, вычисляемые атрибуты(ocl code), можно создавать свои ocl-операции, испольнение SQL, машина состояний для объекта, куча дата провайдеров(причем написать новый для любой базы данных можно не более чем за один день), возможность регистрации своих и замены стандартных сервисов ECO space, версионные данные, lazy fetch, выполнение ocl по отношениюк объектам в памяти и выполнение удаленных OCL, сейчас даже LINQ и даже Silverlight. собственный редактор модели, с возможностью документирования модели и работы нескольким разработчикам одновременно(новое для ECO5), а так же многое другое.
ECO бесплатна для работы с моделями в 12 классов? проектировать можно сколько хочешь, а вот запускать только модели где не более 12 классов. я считаю этого достаточно чтобы померить.


Приступим


как сделать так чтобы работало :)?

  • 1. Нужна Visual Studio 2008 sp1, можно поставить триал.
  • 2. дистрибутив можно взять по адресу: www.capableobjects.com/download.aspx?file=Eco5Test, версии постоянно обновляются поскольку ECO5 еще как бы на бета -тестировании, но работать на нем уже можно :)
    дистирбутив легкий, а процесс установки не займет много времени.
    у меня установлен
    image

Первый проект


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


Создаем проект.

Заходим «File > New > Project» выбираем тип проекта ECO Solution.
image
выбираем WinForm Application остальное можно не трогать.
image
В итоге визард создаст для нас каркас приложения, у меня это три проекта в одном солюшене: SampleProject, SampleProject.Model, SampleProject.EcoSpace. Соответственно главное приложение, модель предметной области или просто модель, и эко пространство (о том что это такое может быть попозже расскажу).


image

Модель предметной области


Придумал небольшую модель для предметной области:
image
автор и редактор оба человеки. Автор пишет статью, редактор проверяет и пропускает или не пропускает статью. все очень просто.
теперь добавляем машину состояния для статьи:
image
ну я думаю можно немного прокомментировать: статья после создания редактируетсяавтором, затем он отправляет ее на публикацию, где редактор проверяет грамматику и орфографию, и либо снимает ее с рассмотрения, либо после того как статья прошла все «проверки» она публикуется.


Теперь усложним немного условия, скажем что автор, уже имеющий больше 10 работ может публиковать свои статьи сам без помощи редактора, ну или статус автоматической публикации может быть присвоен при добавлении автора в нашу систему. Добавим машину состояний для Автора.
image
добавим Автору дополнительный атрибут, AutoPublished, значение по умолчанию для него будет false, но как только кто-то установит его, надо будет изменить состояние автора на AutoPublished.
image
теперь генерим код для классов
image
как мы видим эко сгененрил код для всех классов. класс эко разделен на две части используюя возможность partial описания классов, так же видим что эко испольует и partial методы для реализации дополнительной функциональности. Файл Author.eco.cs будет всегда генериться заново, но наши методы мы будем складывать в файл Author.cs. Нам нужно добавить реализацию метода this.AutoPublishChanging(ref value, ref abortModification);


Введем дополнительный вычисляемый атрибут. количество опубликованных статей.
ArticlesCount:int. поставим для него ocl-выражение.(ECO5 заметил что у меня два раза встречается Name у родителя и у наследника, говорит multipleFeatures Name, поэтому заменил название на FullName, чего туда поставим увидите позже).
image
как видно я задал выражение для вычисления «self.Articles->select(t|t.oclisInState(#Published))->size». поясню немного: мы, используя навигацию, выбираем все статьи автора которые имеют статус Published и считаем их количество.
Теперь можно реализовать логику метода изменения AutoPublish(и не забываем генерить код):
partial void AutoPublishChanging(ref bool value, ref bool abortModification)
{
if (value)
//тут мы вызывает trigger машины состояний чтобы перевести автора в состояние AutoPublished
MakeAutoPublished();

else
if (ArticlesPublished >= 10)
// здесь запрещаем снимать автопубликацию если у человека больше 10 статей.
abortModification = true;
}


теперь еще немного логики: нам необходимо изменить машину состояний для статьи Article, таким образом чтобы при публикации десятой статьи у автора менялось состояние на AutoPublished.


Для тетсирования создадим тест project.
Так пришло время познакомится с PersistenceMapper-ами: открываем проект SampleProject.EcoSpace. этот проект фактически управляет размещением и получением объектов из persistence storage. по умолчанию мы выбрали PersistenceMapperXML, но для теста нам сгодится PersistenceMapperMemory он для тестов и предназначен.
вот и добавляем его. Открываем SampleProjectPMP.cs, перетягиваем PersistenceMapperMemory из панели инструментов.
image
устанавливаем PersistenceMapperProvider-у свойство PersistenceMapper в значение persistenceMapperMemory1 и все наша система готова к тестированию(не забываем генерить код модели).
Доавбляем во вновь созданные тестовый проект необходимые референсы наши два проекта SampleProject.Model и SampleProject.EcoSpace. а также четыре библиотеки ECO: Eco.Handles, Eco.Persistence, Eco.LinqExtender, Eco.Intefaces.
ниже привожу код теста? вроде бы всю функциональность покрыл и все работает.

public SampleProject.SampleProjectEcoSpace ecoSpace = new SampleProject.SampleProjectEcoSpace();
Author _Author = null;
[TestInitialize()]
public void MyTestInitialize()
{
ecoSpace.Active = true;
//создаем тестовые данные
_Author = new Author(ecoSpace);
for (int i = 0; i < 15; i++)
_Author.Articles.Add(new Article(ecoSpace) { Text = string.Format(«Article about {0}», i) });
}
[TestMethod]
public void TestMethod1()
{
// должно быть 15 статей
Assert.AreEqual(15, _Author.Articles.Count);
// из них не одна не должна быть опубликованной
Assert.AreEqual(0, _Author.ArticlesPublished);
// автор не должен быть автопубликуемым
Assert.IsFalse(_Author.AutoPublish);
// берем первую попавшуюся статью
Article art = _Author.Articles[0];
//отправляем на публикацию
art.Publish();
// проверяем
art.SpellCheked();
art.GrammarChecked();
// статья должна быть опубликована
Assert.AreEqual(1, _Author.ArticlesPublished);
// меняем автору что он автопубликуется
_Author.AutoPublish = true;
Assert.IsTrue(_Author.AutoPublish);
//публикуем все статьи
for (int i = 1; i < 10; i++)
_Author.Articles[i].Publish();
// должно быть 10 штук
Assert.AreEqual(10, _Author.ArticlesPublished);
//пытаемся изменить автора и сказать что он не автопубликуется
_Author.AutoPublish = false;
// действие отменено
Assert.IsTrue(_Author.AutoPublish);
}

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

GUI


Открываем форму в приложении SampleProject. теперь для интерфейса нам нужем ContextAgent: открываем Tools->ContextAgent
image
как мы видим на форме уже есть несколько компонент: ecoGlobalActions, ecoAutoForms, ecoDragDrop, ecoListActions, rhRoot. первые четыре компонента представляют собой расширители для элементов GUI, они добавляют дополнительную функциональность контролам: кнопкам, гридам, и т.п. на их основе можно нарастить свои собственные компоненты, или вручную прикрутить к другим, нестандартным контролам. последний компоент представляет собой узловой элемент для формы, т.е. это контекст формы, по умолчанию он указывает только на объектное пространство, но его можно использовать и для задание определенного объекта в пространстве, в контесте которого будут получать данные контролы на форме. например можно задать в качестве контекста экземпляр класса пользователя, а значение установить после выполнения входа, и все данные подгружать относительно этого объекта, а именно используя его либо в качетсве переменной в ocl запросах или непосредственного источника для навигации по ассоциациям. В нашем случае все простно contextAgent Упростил жизнь и мне и вам. я просто составлю форму мастер деталь:
image
такую вот я формочку накатал мышкой и контекстным агентом :) вручную пришлось выставить контекст для currencyManagerHandle, он отслеживает позицию курсора в верхнем гриде чтобы данные в нижнем менялись автоматически.
для того чтобы по двойному щелчку открыть автоформу, нужно в свойствах грида в категории (у меня отсортированы по категориям) ECO|GUI EcoAutoForm on EcoAutoForms = true; для обоих гридов.
Вот и результат работы.
image

Выводы


А чего можно сказать в выводах, это первая статья, я думаю, из цикла. голосуйте, и тогда я буду публиковать их на Хабре.
ECO 5 мощная штука у меня есть опыт разработки и промышленной эксплуатации распределенной системы, которая используя все возможности эко решает очень много полезных для бизнеса задач, размер системы свыше 400 таблиц.
Вопросы?