- Любовные романы
- Фантастика и фэнтези
- Ненаучная фантастика
- Ироническое фэнтези
- Научная Фантастика
- Фэнтези
- Ужасы и Мистика
- Боевая фантастика
- Альтернативная история
- Космическая фантастика
- Попаданцы
- Юмористическая фантастика
- Героическая фантастика
- Детективная фантастика
- Социально-психологическая
- Боевое фэнтези
- Русское фэнтези
- Киберпанк
- Романтическая фантастика
- Городская фантастика
- Технофэнтези
- Мистика
- Разная фантастика
- Иностранное фэнтези
- Историческое фэнтези
- LitRPG
- Эпическая фантастика
- Зарубежная фантастика
- Городское фентези
- Космоопера
- Разное фэнтези
- Книги магов
- Любовное фэнтези
- Постапокалипсис
- Бизнес
- Историческая фантастика
- Социально-философская фантастика
- Сказочная фантастика
- Стимпанк
- Романтическое фэнтези
- Ироническая фантастика
- Детективы и Триллеры
- Проза
- Юмор
- Феерия
- Новелла
- Русская классическая проза
- Современная проза
- Повести
- Контркультура
- Русская современная проза
- Историческая проза
- Проза
- Классическая проза
- Советская классическая проза
- О войне
- Зарубежная современная проза
- Рассказы
- Зарубежная классика
- Очерки
- Антисоветская литература
- Магический реализм
- Разное
- Сентиментальная проза
- Афоризмы
- Эссе
- Эпистолярная проза
- Семейный роман/Семейная сага
- Поэзия, Драматургия
- Приключения
- Детская литература
- Загадки
- Книга-игра
- Детская проза
- Детские приключения
- Сказка
- Прочая детская литература
- Детская фантастика
- Детские стихи
- Детская образовательная литература
- Детские остросюжетные
- Учебная литература
- Зарубежные детские книги
- Детский фольклор
- Буквари
- Книги для подростков
- Школьные учебники
- Внеклассное чтение
- Книги для дошкольников
- Детская познавательная и развивающая литература
- Детские детективы
- Домоводство, Дом и семья
- Юмор
- Документальные книги
- Бизнес
- Работа с клиентами
- Тайм-менеджмент
- Кадровый менеджмент
- Экономика
- Менеджмент и кадры
- Управление, подбор персонала
- О бизнесе популярно
- Интернет-бизнес
- Личные финансы
- Делопроизводство, офис
- Маркетинг, PR, реклама
- Поиск работы
- Бизнес
- Банковское дело
- Малый бизнес
- Ценные бумаги и инвестиции
- Краткое содержание
- Бухучет и аудит
- Ораторское искусство / риторика
- Корпоративная культура, бизнес
- Финансы
- Государственное и муниципальное управление
- Менеджмент
- Зарубежная деловая литература
- Продажи
- Переговоры
- Личная эффективность
- Торговля
- Научные и научно-популярные книги
- Биофизика
- География
- Экология
- Биохимия
- Рефераты
- Культурология
- Техническая литература
- История
- Психология
- Медицина
- Прочая научная литература
- Юриспруденция
- Биология
- Политика
- Литературоведение
- Религиоведение
- Научпоп
- Психология, личное
- Математика
- Психотерапия
- Социология
- Воспитание детей, педагогика
- Языкознание
- Беременность, ожидание детей
- Транспорт, военная техника
- Детская психология
- Науки: разное
- Педагогика
- Зарубежная психология
- Иностранные языки
- Филология
- Радиотехника
- Деловая литература
- Физика
- Альтернативная медицина
- Химия
- Государство и право
- Обществознание
- Образовательная литература
- Учебники
- Зоология
- Архитектура
- Науки о космосе
- Ботаника
- Астрология
- Ветеринария
- История Европы
- География
- Зарубежная публицистика
- О животных
- Шпаргалки
- Разная литература
- Зарубежная литература о культуре и искусстве
- Пословицы, поговорки
- Боевые искусства
- Прочее
- Периодические издания
- Фанфик
- Военное
- Цитаты из афоризмов
- Гиды, путеводители
- Литература 19 века
- Зарубежная образовательная литература
- Военная история
- Кино
- Современная литература
- Военная техника, оружие
- Культура и искусство
- Музыка, музыканты
- Газеты и журналы
- Современная зарубежная литература
- Визуальные искусства
- Отраслевые издания
- Шахматы
- Недвижимость
- Великолепные истории
- Музыка, танцы
- Авто и ПДД
- Изобразительное искусство, фотография
- Истории из жизни
- Готические новеллы
- Начинающие авторы
- Спецслужбы
- Подростковая литература
- Зарубежная прикладная литература
- Религия и духовность
- Старинная литература
- Справочная литература
- Компьютеры и Интернет
- Блог
Дефрагментация мозга. Софтостроение изнутри - Сергей Тарасов
Шрифт:
Интервал:
Закладка:
outFileName="%PROJECT_NAME%.sql"
updateDatabase="true"
targetVersion="2008">
<Param name="Database.Create" value="false" />
… Другие параметры "заклинания"
</Genie>
<! – Будем использовать джинна Oracle – >
<Genie name="OracleDb"
type="GenieLamp.Genies.Oracle.OracleGenie"
assembly="GenieLamp.Genies.Oracle"
active="true"
outDir="%PROJECT_DIR%/../SQL/Oracle-%TARGET_VERSION%"
outFileName="%PROJECT_NAME%.sql"
outFileEncoding="iso-8859-1"
updateDatabase="false"
targetVersion="10g">
<Param name="UniqueIndexConstraint" value="true" />
…
</Genie>
<! – Будем использовать джинна NHibernate для генерации домена – >
<Genie name="NHibernate"
type="GenieLamp.Genies.NHibernate.NHibernateGenie"
assembly="GenieLamp.Genies.NHibernate"
active="true"
outDir="%PROJECT_DIR%/../Domain"
outFileName="%PROJECT_NAME%.Domain.cs"
targetVersion="*">
<Param name="TargetAssemblyName" value="Company.Business.%PROJECT_NAME%.
Domain" />
</Genie>
<! – Будем использовать первого джинна ServiceStack
для генерации интерфейсов к веб-службам – >
<Genie name="ServiceStack Services Interfaces"
type="GenieLamp.Genies.ServicesLayer.ServiceStack.ServicesInterfacesGenie"
assembly="GenieLamp.Genies.ServicesLayer"
active="true"
outDir="%PROJECT_DIR%/../Services.Interfaces"
targetVersion
="*">
</Genie>
<! – Будем использовать второго джинна ServiceStack
для генерации собственно веб-служб – >
<Genie name="ServiceStack Services"
type="GenieLamp.Genies.ServicesLayer.ServiceStack.ServicesGenie"
assembly="GenieLamp.Genies.ServicesLayer"
active="true"
outDir="%PROJECT_DIR%/../Services"
targetVersion="*">
</Genie>
<Configuration>
<! – Конфигурация слоя хранения данных – >
<Layer name="Persistence">
<NamingConvention style="uppercase" maxLength="30">
<Param name="PrimaryKey.ColumnTemplate" value="NI%TABLE%" />
<Param name="PrimaryKey.ConstraintTemplate" value="PK_%TABLE%" />
… Другие шаблоны именований
</NamingConvention>
<Param name="ForeignKey.CreateIndex" value="true" />
<Param name="BooleanValues" value="YesNo"/>
</Layer>
<! – Конфигурация слоя домена – >
<Layer name="Domain">
<Param name="BaseNamespace" value="Company.Business.%PROJECT_NAME%" />
</Layer>
<! – Конфигурация слоя служб – >
<Layer name="Services">
<Param name="BaseNamespace" value="Company.Business.%PROJECT_NAME%" />
</Layer>
<! – Шаблон "Реестр объектов" – >
<Pattern name="Registry">
<Param name="Schema" value="Core" />
<Param name="PersistentSchema" value="CORE" />
<Param name="RegistryEntity.Name" value="EntityRegistry" />
<Param name="TypesEntity.Name" value="EntityType" />
<Param name="TypesEntity.PrimaryId.Type" value="smallint" />
<Param name="PrimaryId.Type" value="bigint" />
</Pattern>
<! – Шаблон "Версия состояния" для хранимых объектов – >
<Pattern name="StateVersion">
<Param name="Attribute.Name" value="Version" />
<Param name="Attribute.Type" value="int" />
</Pattern>
<! – Шаблон "Аудит" для минимального отслеживания изменений – >
<Pattern name="Audit" />
<! – Шаблон "Локализация" – >
<Pattern name="Localization" />
<! – Шаблон "Безопасность" для веб-служб – >
<Pattern name="Security" />
</Configuration>
В описании конфигурации джиннов видно, что его основу составляет сборка, один из классов которой, реализующий интерфейс IGenie, является точкой входа. Каждый джинн имеет как общие для всех параметры, например каталог для выходных файлов, так и специфичные, передаваемые через тег Param, описываемые в документации.
За джиннами следуют конфигурации слоёв. Если для домена и служб можно пока ограничиться спецификацией базового пространства имён, то для слоя хранения, особенно при поддержке более чем одной СУБД, необходимо указать дополнительные ограничения вроде максимальной длины имён.
Заключительная часть конфигурации представляет собой описания шаблонов. Но не тех, о которых идёт речь в книжке «банды четырёх», а о шаблонах реализации типовых задач уровня ядра и системных служб:
• Например, шаблон «Реестр объектов» добавляет к системе возможность ведения централизованного реестра всех создаваемых объектов. Реализован он как соответствующий класс и таблица, ссылка на которые добавляется ко всем другим классам (некоторые классы можно исключить через параметры шаблона).
• Шаблон «Версия состояния» является встроенной в NHibernate возможностью отслеживания конфликтов в многопользовательской среде. Например, если два пользователя изменяют один и тот же объект, то последний из них, сохранивший объект, получит исключение, оповещающее о том, что данные были изменены со времени последнего редактирования. Шаблон реализуется добавлением соответствующего атрибута номера версии ко всем классам.
• Шаблон «Аудит» в простейшем варианте является регистрацией для каждого хранимого объекта информации о времени его создания, последнем редактировании и авторе.
• Шаблон «Локализация» добавляет в генерируемый код возможность перевода сообщений в рамках технологии GNU gettext.
• Наконец, шаблон «Безопасность» в простейшем варианте ограничивает доступ к веб-службам через механизм аутентификации, логику которой необходимо реализовать в переопределяемом методе соответствующего класса. Например, обратиться к стороннему LDAP или непосредственно к базе данных с регистрационной информацией для проверки имени пользователя и хеша пароля.
Теперь, если запустить «заклинатель» с параметром файла конфигурации проекта и не будет обнаружено ошибок, на выходе мы получим инициализированные структуры баз данных и готовые к компиляции файлы. Рассмотрим их чуть подробнее.
Слой хранения (СУБД)
Джинны SQL Server и Oracle создадут нам в указанном каталоге подкаталоги, соответствующие целевой СУБД и её версии. В каждом подкаталоге находятся три SQL-скрипта, предназначенные, соответственно, для создания, обновления или удаления схемы БД.
Если посмотреть на созданные в СУБД структуры, то мы увидим, что из одной и той же модели логического уровня были созданы две реализации, различающиеся на физическом уровне. Например, используемые типы данных различаются. С другой стороны, необходимость поддержки слоем домена сразу двух СУБД приводит к тому, что вместо оптимального, но специфичного для SQL Server типа bit для поддержки булевых величин используется принятый в среде Oracle символьный тип.
Рис. 20. Результат работы джинна SQL Server
Рис. 21. Результат работы джинна Oracle
Слой домена (NHibernate)
Джинн NHibernate генерирует три C#-файла и один XML-файл проекции (маппинга) классов на структуры хранения.
Все классы домена являются расширяемыми (partial), что позволяет разработчику вынести специфичные не поддерживаемые моделью реализации свойств и методов классов в отдельные файлы.
Перечисляемый тип создаётся вместе с классами, позволяющими локализовать пользовательские названия его элементов, описанные в модели. По умолчанию будет использован язык модели, перевод необходимо осуществлять в технологии gettext.
Рис. 22. Перечисляемый тип слоя домена и его локализация
Рис. 23. Класс «Финансовый год» слоя домена
Для определяемых моделью сущностей генерируются классы, содержащие кроме соответствующих объявленным атрибутам свойств ещё и группу служебных методов для управления объектами, например, для сохранения или выборки по запросу на HQL или даже SQL. Такие методы часто используют служебные классы, объявленные в DomainSupport.cs.
Для объявленных в модели операций генерируется соответствующий метод интерфейса. Реализовать их нужно программисту в рамках расширения partial-класса.
Рис. 24. Класс «Учётный период» слоя домена
Отображение классов на структуры РСУБД соответствует стратегии «одна таблица на подкласс без дублирования атрибутов предка», достаточно хорошей в большинстве случаев, но и она может быть изменена.
Фрагмент файла проекции для класса «Финансовый год»
<!-Engine.FiscalYear->
<class name="Domain.Engine.FiscalYear" table="FISCAL_YEAR" schema="MYAPP">
<id name="Id" access="property" column="NIFISCAL_YEAR">
<generator class="native">
<param name="sequence">MYAPP.SEQ_FISCAL_YEAR</param>
</generator>
</id>
<version name="Version" column="VERSION" type="int" access="property" />
<set name="Periods" table="MYAPP.PERIOD" inverse="true" lazy="true" cascade="none">
<key column="NI_FISCAL_YEAR" />
<one-to-many class="Domain.Engine.Period" />

