Материал предоставлен сайтом Территория Дмитрия Новоженова (http://www.novojonov.ru)
В данной статье рассматривается применяемая мной технология разработки, проектирования, реализации и поддержки корпоративных приложений, ориентированных на применение Microsoft SQL, Microsoft Windows Server, Microsoft .Net Framework и Microsoft ASP.NET.
Среди многообразия приложений к корпоративным принято относить определенный класс приложений, имеющих ряд общих черт. Совокупность этих черт и определяет то, что можно назвать корпоративным приложением, а что нет. Основной отличительной чертой корпоративного приложения является его узкая специализация. Практически все функции приложения можно определить тремя пунктами:
Безусловно, приведенный функционал предельно упрощен, но удаление одного из этих пунктов делает из корпоративного приложения прикладную программу. Описанный функционал, также, однозначно определяет и архитектуру приложения. На данный момент наиболее популярна трехуровневая архитектура, в которой, в соответствии с функционалом, выделяется три уровня:
Уровни приложения могут быть как физическими, когда компоненты приложения физически размещаются на разных серверах, так и логическими, когда они выделяются в отдельные блоки кода.
В развитии современных приложений наблюдается устойчивая тенденция, которая еще больше сближает различные корпоративные приложения. Эта тенденция - переход к Web-технологиям.
У Web есть несколько достоинств настолько существенных, что они однозначно определяют выбор платформы при проектировании нового приложения или внедрения. К этим достоинствам относятся:
Любое приложение уровня предприятия использует один и тот-же набор системных сервисов в своей работе. Набор сервисов однозначно определяется требуемым функционалом и включает в себя:
Функционал сервера баз данных (БД) составляет постоянное и надежное хранение данных а также поддержка бизнес-транзакций, т.е. наборов системных операций, имеющих смысл для бизнеса и составляющих, с его точки зрения, единую и неделимую операцию. Также к функциям сервера управления базами данных относится поддержка реляционной модели хранимых данных, включая обеспечение ее целостности и непротиворечивости.
Функционал сервера приложений составляют преобразование и модификация данных. Хранящиеся в БД данные не представляют ни смысла ни ценности для бизнеса, поскольку структура хранения данных значительно отличается от структуры их представления. Задача сервера приложения - преобразовать данные от вида, в котором они хранятся к виду, который будет понятен конечному пользователю системы, бизнесу. Текже задача сервера приложений - обработка запросов конечных пользователей на модификацию хранящихся данных в соответствии с действующими правилами бизнес-логики.
Задача уровня представлений - визуализация данных и предоставление конечному пользователю интерфейса управления данными предприятия. В данном контексте слово интерфейс используется в техническом смысле, как точка взаимодействия пользователя и системы.
Основным фактором, который следует учитывать при разработке любого корпоративного приложения является следующее утверждение: "Все уже было разработано до нас". Годами наработаны шаблоны, решающие типовые задачи, каковой и является задача построения корпоративного приложения. Для этих целей я предпочитаю использовать технику паттернов, т.е. повторяющихся идей и отличающихся реализаций.
Использование паттернов является "религией", враждебной использованию компонентов. Компоненты, как и паттерны, применяются для обеспеечения повторного использования кода. Использование компонентов, будучи светлой идеей, является затруднительным в данном случае, поскольку быстро меняющиеся требования бизнеса требуют частого рефакторинга кода. В этом случае компоненты проигрывают шаблонам.
Любое приложение, претендующее на звание корпоративного, является априори большим приложением. Потребность в построении корпоративных приложений или, иначе говоря, приложений уровня предприятия, возникает тогда и только тогда, когда предприятие попадает в "революционную" ситуацию, при которой деятельность нужно осуществлять по-старому а вот управлять этой деятельностью нужно по-новому.
Такая ситуация складывается, как правило, с ростом объемов и децентрализацией деятельности. Ключевой момент - рост объемов. Предприятие растет, бизнес-процессы усложняются, в голове уже все не удержать. Тогда и вспоминают про корпоративные приложения. Именно это и определяет сложность и объем приложения. Вывод из этих сентенций крайне прост: если менеджеры предприятия не могут удержать все в голове, разработчику тоже вряд-ли удастся. Поэтому проектирование играет ключевую роль в процесе разработки.
Основная цель разработки корпоративного приложения - моделирование бизнес-процессов предприятия. Бизнесу требуется максимально полное отражение приложением существующих процессов, включая терминологию, правила и нюансы. А "клиент всегда прав", не так-ли? Поэтому проектирование приложения, фактически, сводится к построению модели предприятия "в натуральную величину".
Теоретики программирования давно проработали процесс моделирования и создали UML, Universal Modeling Language, универсальный язык моделирования. Но есть проблема, во всяком случае я ее так рассматриваю. Как любая универсальная система, концепция UML всеобъемлюща и, как следствие, крайне сложна. Что-то сродни философскому камню. Очень хорошо, если удастся подробно изучить UML в полном объеме, но вряд-ли это целесообразно, поскольку дедушки Паретта никто не отменял, а он говорит, что 20% усилий покроюи 80% потребностей.
Если я внимательно читал классиков, они тоже со мной согласны. RUP, Rational Unified Process, в чистом виде никто из моих знакомых не использует за его избыточностью. Меня, например, очаровывает процесс ICONIX, представляющий собой усеченный вариант RUP. Но и его я использую не в чистом виде, мой процесс - адаптация идеи ICONIX для моих нужд. Мой процесс включает в себя следующие шаги:
Каждый из упомянутых выше этапов обязтально должен окончиться составлением документа, который внесет свою лепту в общий проект. Под документом я предполагаю не "тупой лобовой", а неформальный подход. Оформление ТЗ по ГОСТ - это здорово, но отнимет столько времени, что заказчик занервничает. Может даже отсановить финансирование =) Именно по этому стоит создавать гранулярные документы и поэтапно обсуждать их с заказчиком вместо долгого написания длинного и хорошего документа. Возникает риск создать отличный документ но дома и за свой счет.
Интервьюирование заказчика имеет важнейшее значение. Цель данного этапа - оказаться "в шкуре" людей, которые будут пользоваться разрабатываемым приложением. Главное на данном этапе - помнить, что софт пишется для пользователей. Не для программистов, не для администраторов, даже не для руководства, а для пользователей. В результате должен быть составлен документ, который на понятном пользователю языке с картинками показывает что именно получит заказчик когда нетленка будет закончена.
Иными словами - составление глоссария. Программисты сколнны мыслить абстрактными категориями. Мы создаем новое приложение и при этом слишком часто забываем о том, что та деятельность, которую мы беремся автоматизировать уже ведется и уже сложились термины и определения. Задача данного этапа собрать все термины и определия, используемые заказчиком и определить однозначное трактование каждого из них в рамках разрабатываемого приложения. Без этого заказчику будет "жать" новое приложение "спасибо" разработчик не получит. Результатом данного этапа должен быть глоссарий.
В автоматизируемых процессах, как правило, задействовано значительное количество человек. Но мыслить в категориях людей может позволить себе заказчик но не разработчик. Разработка приложения может осуществляться исключительно в терминах ролей. Результатом этого этапа должен быть документ, содержащий список ролей с полным описанием функционала каждой роли.
В своей деятельности люди оперируют какими-то объектами. Договорами, контактами, отчетами. На данном этапе нужно определить состав этих объектов, характеристики каждого из них и связи, имеющиеся между ними. Иными словами составить граф модели предметной области. Результатом этапа должна быть аннотированная схема, описывающая объекты предметной области.
Пользователи что-то делают с объектами. Визируют договора, заводят контакты, составляют отчеты. Именно глаголы, примененные к существительным важны на данном этапе. Задачей этого этапа является определение действий, которые будут применять субъекты к объектам. Результатом данного этапа должен быть документ, определяющий и конкретизирующий действия, которые смогут предпринимать пользователи в системе. Единственная форма данного документа, которая удобна мне и моим заказчикам - набор скрин-шотов интерфейсов. Пользователь любит картинки, а мне потом верстать легче =)
На данном этапе определяются последствия, которые возымеют прецеденты. Данный этап явялется одновременно самым простым и самым сложным. Четкость и понятность бизнес-логики (ее и логикой-то можно только в шутку назвать) - притча во языцех. Основное внимание на данном этапе следует уделить пониманию процессов, которые предстоит автоматизировать и условий, которые определяют эти процессы. Для каждого процесса обязательно определяются точки входов и выходов, лежащие в пространстве прецедентов. Результатом данного этапа должен служить набор диаграмм, по одной для каждого из автоматизируемых процессов.
Логическим результатом проектирования является составление ТЗ, технического задания. Составление ТЗ не представляет собой никакой сложности, поскольку является, по сути, сводкой всех документов, порожденных на предыдущих этапах. Формальность ТЗ - предмет соглашения заказчика и исполнителя, мне никогда не доводилось писать формальных (по ГОСТ) ТЗ, поскольку заказчик никогда этого не требовал. Но есть и резкое отличие данного этапа от предыдущих. ТЗ должно быть согласовано и утверждено. И это должно быть где-то зафиксировано.
Не следует пытаться проделать все указанные выше шаги последовательно. Проектирование - процесс итеративный. На каждом этапе выясняется, что мы что-то упустили и не грех вернуться к какому-либо этапу и дополнить, расширить, исправить... Более того, мне наиболее понятна и удобна "спиральная" модель, при которой движение проектирования идет по спирали, когда каждый штрих нанаосится крупными мазками, потом уточняется по мере формирования общей картины. И так раз за разом, круг за кругом, виток за витком.
Также при проектировании приложения следует учитывать некоторые особенности, характерные для любого заказчика и исполнителя. Может где и есть иделальный заказчик и исполнитель без недостатков, но лучше исходить из утверждения "все мы люди" =) Эти особенности таковы:
Таким образом проектирование - основной процесс разработки, призванный свести к минимуму различия в образах мышления заказчика и исполнителя. При проектировании мы фактически договариваемся с заказчиком что он получит и сколько за это заплатит (времени мы потратим). Пренебрежение проектированием приведет к тому, что модель не будет отражать предметной области, приложение придется многократно переписывать и у заказчика сложится вполне определенное мнение о Вашем профессионализме.
Любое корпоративное приложение нуждается в хранении данных. Идеальным хранилищем, на данный момент, является база данных (БД). БД - понятие слишком широкое, это просто набор связанных данных. Для нужд корпоративного приложения всерьез рассматривается исключительно одна из наиболее распространенных систем управления базами данных (СУБД), к которым относятся:
Безусловно, существует еще огромное количество хороших, отличных и промышленных движков, например IBM DB2, SyBase, MySql, PostgreSql и др. Но, должен заметить, что в области коммерческих решений производители говорят просто: "MS SQL, Oracle и другие OLE DB совместимые". Таким образом, БД - заложница платформы. Если мы говорим о .NET решении, мы подразумеваем MS SQL.
Столь суровый выбор БД определяется ничуть не желанием включить в описание продукта громкое имя и тем самым приобщиться к лику. Просто СУБД должна обеспечивать определенный набор функций, используемых всеми корпоративными приложениями. И отсутствие этих функций изрядно обесценивает системы их не несущие. Смешной пример: остутствие в PostgreSql дистрибутива для Windows задвинул отличную СУБД настолько глубоко, что MySql, которая на порядок беднее, находится в рейтинге на порядок выше.
Требования, выдвигаемые к СУБД, определяются спецификой приложений, транзактное обновление и аналитическая обработка. Выдвигаемые мной требования таковы:
Безусловно, выдвинутые требования можно и нужно ранжировать с учетом конкретной платформы, но есть и оборотная сторона медали. Чаще всего в компании принято использование какой-либо платформы и не в наших силах пересмотреть этот выбор. В таком случае остается только вспоминать свои требования и прикидывать, какими проблемами грозит их несоблюдение.
В компании, где я работаю, принято использовать Microsoft SQL Server. Мне остается только порадоваться тому, что Microsoft SQL Server удовлетворяет всем требованиям, которые я выдвигаю.
Выбранная мной схема построения БД не отличется особой оригинальностью. Просто концепция многократно опробована и заслужила фиксации. БД строится как высоконормализованное ориентированное на транзакции хранилище, инкапсулирующее доступ к данным посредством хранимых процедур и обеспечивающее ссылочную целостность данных.
Нормализация хранилища - штука обоюдоострая и может порезать. Одна из функций - наполнение, выигрывает от нормализации, другая - аналитика, проигрывает. Мой опыт показывает, что лучше построить высоконормальное хранилище, обеспечивающее целостность данных, а аналитику возложить на плечи уровня бизнес-логики. В веб-приложениях он все равно практически всегда простаивает. Или, если объем данных велик, организовать два хранилища, одно для исходных, другое для аналитических данных и организовать подписку аналитики на сырье. Однозначный выигрыш от нормализации заключается в следующем:
Из всего многообразия типов данных, предоставляемых современными СУБД, мне приходится использовать лишь ограниченное подмножество, которого мне достаточно для обеспечения хранения любой информации. К этим типам относятся:
Указанный набор полностью покрывает мои потребности и не оставляет желать лучшего. Считается хорошим тоном использовать национальные типы данных, UNICODE нынче в моде =) Но в процессе работы я обратил внимание, что национальные символы в БД никто не кладет и использование префикса n лишь удваивает объем хранения и снижает скорость обработки.
Аналогично, можно спорить и насчет хранения файлов в БД. Популярно мнение, что это лишь тормоза и ничего более. Мой опыт показал, что правильная орагнизация БД, включающая в себя секционирование таблиц и вынесение BLOB в отдельные файловые группы позволяет обеспечить целостность данных без потери быстродействия. Поэтому я придерживаюсь концепции единого хранилища.
Соглашение об именах - первое, что стоит написать при разработке мало-мальски объемного приложения. Иначе возникает риск запутаться самому и запутать других. Особенностью корпоративных приложений является их живучесть и написанное однажды придется переписывать и дополнять вновь и вновь. Существует много схем именования объектов, не существует лишь хороших. Плохие, правда, встречаются =) Я использую следующую схему:
Таблицы БД - нижний уровень хранения данных. При проектировании таблиц я давно и успешно использую шаблон "таблица на объект". При этом подходе для каждого постоянного объекта создается своя табличка данных. Структура таблицы однозначно определяется на этапе бизнес-анализа но может быть уточнена на этапе проектирования. При построении таблиц используются следующие принципы:
Хранимые процедуры - надежное средство инкапсуляции, позволяющее создать дополнительный уровень абстрагирования данных приложения от его логики. Или ее отсутствия =) Доступ к данным должен осуществляться исключительно посредством хранимых процедур, поскольу лишь они могут надежно гарантировать атомарность операций. Также немаловажно то, что надлежаще спроектированный набор хранимок вполне позволит "на лету" менять не только данные БД, но и ее схему, например создать дополнительную секцию излишне разросшейся таблицы.
При проектировании хранимых процедур следует придерживаться следующих принципов, соблюдение которых позволит максимально правильно построить приложение в части соответствия многоуровневой модели и этим значительно облегчить как процесс разработки так и процесс модификации приложения. Я руководствуюсь следующими принципами при построении хранимок:
Хранимые процедуры являются последним рубежом обороны БД. Доступ к хранимкам должен определяться при их создании. Оптимальным с моей точки зрения является создание серверной роли, предоставление этой роли права исполнения хранимых процедур и назначение на эту роль пользователя, от имени которого будет работать приложение. Такая схема позволит, в случае чего, оперативно изменить круг лиц, имеющих доступ к данным.
Материал предоставлен сайтом Территория Дмитрия Новоженова (http://www.novojonov.ru)