Интерфейсы доступа к службам также содержат описания перечислимых типов с локализацией, классы DTO для передачи состояния между программой-клиентом и доменом, классы для непосредственного доступа к вызовам служб.
Рис. 27. Перечисляемый тип слоя веб-служб
Рис. 28. Классы вызова специфицированных методов
Рис. 29. Классы вызова веб-служб, касающихся «финансового года»
Рис. 30. Класс адаптера для работы с объектом «Финансовый год»
Рис. 31. Класс адаптера для работы с коллекцией объектов «Финансовый год»
Работать с DTO и коллекциями не слишком комфортно, проявляется много ненужных деталей. Но если обернуть операции с DTO адаптерами, то код становится гораздо более читаемым и коротким.
Пример работы с DTO
CurrencyDTO curr1 = new CurrencyDTO();
curr1.Code = "RUR";
curr1.Name = "Currency 1";
UnitOfWorkDTO uow = new UnitOfWorkDTO();
uow.Save(curr1);
PersistenceRequest prq1 = new PersistenceRequest();
prq1.UnitOfWork = uow;
PersistenceResponse prr1 = client.Post
Assert.IsFalse(prr1.CommitResult.HasError, prr1.CommitResult.Message);
Пример работы с адаптерами
Currency curr1 = new Currency();
curr1.Code = "RUR";
curr1.Name = "Currency 1";
CommitResult cr1 = curr1.Save();
Assert.IsFalse(cr1.HasError, cr1.Message);
Программа-клиент
В рамках простейшего WinForms-приложения создадим форму, содержащую сетки отображения финансовых годов и их периодов. Не вдаваясь в технику разработки приложений этого типа, просто приведу фрагменты кода, запрашивающие у служб коллекции соответствующих типов.
Извлечение списка финансовых годов, отфильтрованного по названию
FiscalYearCollection years = FiscalYearCollection.GetByQuery(
"from FiscalYear where Name like: name order by Name",
new ServicesQueryParams()
AddParam("name", txtYearName.Text)
);
dgvYears.DataSource = years;
Извлечение списка учётных периодов заданного года
PeriodCollection periods = PeriodCollection.GetByQuery(
"from Period where FiscalYear.Id =:yearId order by FromDate",
new ServicesQueryParams()
AddParam("yearId", CurrentYear.Id),
0, 1000);
dgvPeriods.DataSource = periods;
Запускаем клиентское приложение, предварительно запустив сервер веб-служб, и видим на экране примерно такую картинку, как на рис. 32.
Рис. 32. Форма отображения финансовых годов и учётных периодов
Остановиться и оглянуться
Рассмотренная выше подсистема состоит из минимального набора слоёв трёхзвенной архитектуры на основе веб-служб. Тем не менее даже в таком минимальном варианте обилие деталей, промежуточных и служебных классов, проекций и преобразований должно дать представление о проблеме сложности современного состояния софтостроения.
Одним из способов обхода этой проблемы является описанная технология программной фабрики, несомненно далёкая от совершенства и ограниченная в наборе целевых платформ.
Какова же эффективность?
Если рассмотреть метрики относительно небольшого проекта, то 40 прикладных сущностей в модели, состоящей примерно из 600 строк XML-описаний, порождают:
• около 3 тысяч строк SQL-скриптов для каждой из целевых СУБД;
• порядка 10 тысяч строк домена;
• 1200 строк XML для проекций классов на реляционные структуры (таблицы);
• около 17 тысяч строк веб-служб и интерфейсов.
Таким образом, соотношение числа строк мета-кода описания модели к коду его реализации на конкретных архитектурах и платформах составляет около 600 к 30 тысячам или 1 к 50.
Это означает, что оснащённый средствами автоматизации программист с навыками моделирования на этапе разработки рутинного и специфичного для платформ/архитектур кода производителен примерно так же, как и его 50 коллег, не владеющих технологией генерации кода по моделям. Любое внесение изменений в модель тут же приводит в соответствие все генерируемые слои системы, что ещё более увеличивает разрыв по сравнению с ручными модификациями. Наконец, для генерируемого кода не нужны тесты. Производительность возрастает ещё как минимум вдвое.
Даже если принять во внимание, что доля рутинного и прочего инфраструктурного кода по отношению к прикладному, то есть решающему собственно задачи конечных пользователей, снижается с масштабом системы, есть о чём поразмыслить в спокойной обстановке.
Cherchez le bug, или Программирование по-французски
Этот рассказ я написал более 10 лет назад, летом 2001 года, в поездках на пригородном поезде между Парижем и Moulin-Galant, где размещался филиал IBM, и поначалу сомневался в необходимости его включения в книгу. Но, просмотрев старый текст, с некоторым удивлением я обнаружил, что если заменить аббревиатуры в названиях технологий на «новые и прогрессивные», то суть повествования останется прежней. Изменится ли что-нибудь ещё через 10 лет, покажет время.
Хаос наступает внезапно