Сам по себе я довольно ленивый программист. Наверно поэтому меня долгое время преследовала мысль о создании инструмента, пригодного для решения широкого круга задач небольшого предприятия. Так появился архитектурный шаблон корпоративной информационной системы, который я первым делом применил в разработке web-платформы предприятия в виде CMS/CMF OpenKit.net.
Изобретение велосипедов не есть мое любимое занятие. Кроме того, я осознаю тот факт, что большинство новых софтверных технологий основано на идеях полувековой давности. Поэтому, впервые подумав о реализации своей мечты, я направился в книжный магазин, в надежде раздобыть кого-нибудь из классиков.
Первой попалась книга Бертрана Мейера «Объектно-ориентированное конструирование программных систем» (увесистый кирпич на 1000 страниц, а с другой стороны – кому сейчас легко?). По мере прочтения усиливалось ощущение того, что это именно то, что мне нужно. Представьте себе: можно начать писать приложение для бухгалтерии, постепенно добавлять все новые и новые фичи, а потом, через какое-то время, оглянуться, и – бац – а прога то уже оказывается для управления орбитальной станцией!
Доля шутки в этой шутке, конечно же, есть, но в основном – правда: у реальной системы не должно быть основной функции. «Что делает эта система?» — это последний вопрос, который должен задавать проектировщик. Если Вы впервые узнали об этом только сейчас, то, скорее всего, к объектно-ориентированному программированию Вы не имеете никакого отношения, даже если очень любите слова «класс» и «объект». Вот так вот. Сам не знал, пока не прочитал об этом.
Особенно меня заинтересовала идея составления систем из кластеров, которую я и попытался воплотить в проекте в меру своего понимания и возможностей. В итоге, благодаря универсальности .NET, получилась даже более универсальная система, чем я предполагал изначально. Например, оказалось, что из «нетовских» кластеров можно построить целый город разнотипных (web, winForms, Console, Remoting services и т.п.) приложений, построенных, тем не менее, по одному архитектурному шаблону.
В целом, это еще один вариант старой абстрактной и широко распространенной схемы «ядро (движок, оболочка) + модули». К сожалению, ее реализации часто страдают одной серьезной болезнью: модули, так или иначе, интегрируются с ядром. Из-за этого количество взаимосвязей внутри системы растет в геометрической прогрессии при добавлении новых функций. Вносить изменения разработчикам с каждым разом становится все труднее и труднее, стоимость сопровождения растет столь же стремительно и неизбежно наступает момент, когда разработчики теряют контроль над громоздкой и уже супер дорогой системой.
Лекарство от этого только одно: автономные модули с одной стороны, и полная независимость оболочки от содержимого модулей с другой. Приняв «модуль=кластер», привожу вариант инструмента, пригодного для решения широкого круга прикладных корпоративных задач и не страдающего выше упомянутой болезнью.
Решение состоит из двух частей:
1. API автономного модуля, общий для всех разнотипных (web, winForms, Console, Remoting Services и т.п.) модулей, разрабатываемых в компании…
2. Одна графическая оболочка для каждого типа приложений (для Web – своя, для winForms – своя и т.д.), которая предоставляет доступ к этим компонентам и организует работу с ними посредством этого API.
Принципиальная схема решения приведена на рисунке ниже:
Предлагаемая архитектура корпоративной информационной системы и ее модуля.
1. Архитектурный шаблон модуля
Графически структуру модуля можно представить так:
Кластер Реализует открытый (public) абстрактный класс, который оболочка (например, CMF) ищет в модуле (в dll сборке) через .Net Reflection. Именно от этого класса CMF «узнает» о том, какая функциональность заключена в модуле, имеет ли он web-фасад, на основании чего выясняется, может ли он быть зарегистрирован в web-оболочке.
Задача кластера – объединить связанные по смыслу прикладные объектные модели. Это административная единица управления функционалом программного комплекса.
Web-фасад – Это класс с открытым интерфейсом, через который CMF узнает, какие именно web-адаптеры содержатся в данном модуле и через который она работает с ними.
Web-адаптер – это класс, который предоставляет графический web-интерфейс для работы с какой-то частью прикладной объектной модели. Например, выводит список статей. Тем, кто знаком с ASP.NET, можно думать о нем как об ascx контроле, только размещенном не в отдельном ascx файле, а в сборке.
Точно также может быть фасад и адаптеры для winForms. Адаптером в этом случае будет класс формы, который можно передавать с сервера в графическую оболочку на клиента по Remoting и там запускать. Идею реализации этого можно найти на сайте RSDN в статье семилетней давности «Использование Remoting в multitier приложениях»
Обратите внимание на то, что изменения в структуре данных и связанные с ними необходимые изменения в графических интерфейсах не требуют вмешательства в код разных программ, но производятся в пределах всего одной сборки.
Более детальное описание модуля можно найти в руководстве разработчика на сайте проекта , где также есть его исходный код.
2. Графическая оболочка.
Главная задача оболочки – дать пользователю доступ к функционалу модулей. В оболочку как в мозаику, собираются предоставляемые ими графические интерфейсы. Например, web-оболочка (CMF) организует работу с HTML интерфейсами, winForms оболочка – с формами и т.д… Добавление/удаление модулей из оболочки производится исключительно программно, без ручной настройки в куче файлов. По идее это должна быть относительно простая часть архитектуры, которую в принципе не должны затрагивать никакие изменения в прикладных объектных моделях…
Такая архитектура решает сразу три вопроса: корпоративного интерфейса, единой аутентификации и развертывания. Соответственно, все эти вопросы снимаются с прикладных модулей (приложений), тем самым, существенно упрощая их.
Что касается развертывания, то в случае winForms на клиентские машины достаточно поставить только оболочку, а вся прикладная начинка, включая GUI модулей, будет находиться на сервере. Таким образом, даже развертывание и сопровождение приложений winForms ничем не будет отличаться от web-приложений, требуя внесения изменения только в одном месте (на сервере), что упрощает (удешевляет) администрирование системы.
Самое интересное, что стирается принципиальная разница между сайтом, настольным приложением и комплексным решением предприятия, поскольку в основе их всех лежат одни и те же модули. Именно поэтому можно, например, начать с сайта-визитки и постепенно превратить ее в платформу всего предприятия, расширяя конфигурацию, но при этом не меняя архитектуру системы!
Однако, при реализации я наткнулся на большой подводный камень. Хотя такая архитектура оказывается возможной только благодаря универсальности .NET, не смотря на все усилия, мне не удалось вписать в нее ASP.NET. Загвоздка в том, что с одной стороны, ascx контролы и сборки dll, невозможно «оторвать» от aspx страниц – между ними неустранимая жесткая связь, с другой стороны, aspx страницы не возможно произвольно запускать подобно winForms, без предварительной привязки к файловой системе. Попытка натянуть концепцию winForms на web (основная идея ASP.NET) до конца оказалась как-то не доведена.
Следствием этого, при проектировании CMF OpenKit.net, стал вынужденный отказ от того, что считается технологией ASP.NET. Это повлекло как положительные, так и отрицательные моменты. Минусом стало то, что разработчик модулей CMF может использовать встроенные во Framework элементы управления только программно. Плюсом – то, что разработчику теперь можно вообщезабить на забыть про ASP.NET, сохранив возможность компиляции кода.
Вообще, идея натянуть концепцию winForms на web лично мне представляется довольно сомнительной. В приложениях winForms без компонентного GUI невозможно обойтись в принципе. Но в web, с его HTML, CSS, JavaScript …? Извините. Упрощение малозначимых аспектов, таких, например, как зашивка интерфейсных примитивов в серверные элементы управления и т.п., стоило гигантского усложнения технологии в целом. Впрочем, как оказалось, без знания ASP.NET вполне можно обойтись при разработке web-приложений на .Net. Ни разработчикам модулей, ни администраторам OpenKit, знание ASP.NET не требуется вообще, что, имхо, значительно упростило жизнь.
В итоге имеем: вместо кучи разрозненных приложений написанных неизвестно как и неизвестно на чем – десятки модулей, возможно даже разнотипных, но с одинаковой архитектурой, написанных на одном языке (не считая JavaScript), по одному стандарту и объединенных в одной — двух графических оболочках. Стоимость сопровождения стремится к минимальной, корпоративная информационная система в целом упрощается и, следовательно, становится более надежной и дешевой в сопровождении.
Для небольшой компании это решение может стать недорогой альтернативой ERP и тому подобным системам. Ее разработчики могут своими силами создавать только ту функциональность, которая реально востребована на данном предприятии, не переплачивая за избыточную функциональность и недостаточную гибкость покупных решений с одной стороны и избегая «лоскутной автоматизации» из кучи разношерстных программ с другой.
P.S. Лень: качество, которое заставляет прилагать больше усилий для снижения общих затрат энергии. Она заставляет писать программы, облегчающие труд, и документировать написанное, чтобы вам не пришлось отвечать на лишние вопросы. (Larry Wall, цитирую по Стиву Макконелу «Совершенный код», М. 2005, стр. 810)
Изобретение велосипедов не есть мое любимое занятие. Кроме того, я осознаю тот факт, что большинство новых софтверных технологий основано на идеях полувековой давности. Поэтому, впервые подумав о реализации своей мечты, я направился в книжный магазин, в надежде раздобыть кого-нибудь из классиков.
Первой попалась книга Бертрана Мейера «Объектно-ориентированное конструирование программных систем» (увесистый кирпич на 1000 страниц, а с другой стороны – кому сейчас легко?). По мере прочтения усиливалось ощущение того, что это именно то, что мне нужно. Представьте себе: можно начать писать приложение для бухгалтерии, постепенно добавлять все новые и новые фичи, а потом, через какое-то время, оглянуться, и – бац – а прога то уже оказывается для управления орбитальной станцией!
Доля шутки в этой шутке, конечно же, есть, но в основном – правда: у реальной системы не должно быть основной функции. «Что делает эта система?» — это последний вопрос, который должен задавать проектировщик. Если Вы впервые узнали об этом только сейчас, то, скорее всего, к объектно-ориентированному программированию Вы не имеете никакого отношения, даже если очень любите слова «класс» и «объект». Вот так вот. Сам не знал, пока не прочитал об этом.
Особенно меня заинтересовала идея составления систем из кластеров, которую я и попытался воплотить в проекте в меру своего понимания и возможностей. В итоге, благодаря универсальности .NET, получилась даже более универсальная система, чем я предполагал изначально. Например, оказалось, что из «нетовских» кластеров можно построить целый город разнотипных (web, winForms, Console, Remoting services и т.п.) приложений, построенных, тем не менее, по одному архитектурному шаблону.
В целом, это еще один вариант старой абстрактной и широко распространенной схемы «ядро (движок, оболочка) + модули». К сожалению, ее реализации часто страдают одной серьезной болезнью: модули, так или иначе, интегрируются с ядром. Из-за этого количество взаимосвязей внутри системы растет в геометрической прогрессии при добавлении новых функций. Вносить изменения разработчикам с каждым разом становится все труднее и труднее, стоимость сопровождения растет столь же стремительно и неизбежно наступает момент, когда разработчики теряют контроль над громоздкой и уже супер дорогой системой.
Лекарство от этого только одно: автономные модули с одной стороны, и полная независимость оболочки от содержимого модулей с другой. Приняв «модуль=кластер», привожу вариант инструмента, пригодного для решения широкого круга прикладных корпоративных задач и не страдающего выше упомянутой болезнью.
Решение состоит из двух частей:
1. API автономного модуля, общий для всех разнотипных (web, winForms, Console, Remoting Services и т.п.) модулей, разрабатываемых в компании…
2. Одна графическая оболочка для каждого типа приложений (для Web – своя, для winForms – своя и т.д.), которая предоставляет доступ к этим компонентам и организует работу с ними посредством этого API.
Принципиальная схема решения приведена на рисунке ниже:
Предлагаемая архитектура корпоративной информационной системы и ее модуля.
1. Архитектурный шаблон модуля
Графически структуру модуля можно представить так:
Кластер Реализует открытый (public) абстрактный класс, который оболочка (например, CMF) ищет в модуле (в dll сборке) через .Net Reflection. Именно от этого класса CMF «узнает» о том, какая функциональность заключена в модуле, имеет ли он web-фасад, на основании чего выясняется, может ли он быть зарегистрирован в web-оболочке.
Задача кластера – объединить связанные по смыслу прикладные объектные модели. Это административная единица управления функционалом программного комплекса.
Web-фасад – Это класс с открытым интерфейсом, через который CMF узнает, какие именно web-адаптеры содержатся в данном модуле и через который она работает с ними.
Web-адаптер – это класс, который предоставляет графический web-интерфейс для работы с какой-то частью прикладной объектной модели. Например, выводит список статей. Тем, кто знаком с ASP.NET, можно думать о нем как об ascx контроле, только размещенном не в отдельном ascx файле, а в сборке.
Точно также может быть фасад и адаптеры для winForms. Адаптером в этом случае будет класс формы, который можно передавать с сервера в графическую оболочку на клиента по Remoting и там запускать. Идею реализации этого можно найти на сайте RSDN в статье семилетней давности «Использование Remoting в multitier приложениях»
Обратите внимание на то, что изменения в структуре данных и связанные с ними необходимые изменения в графических интерфейсах не требуют вмешательства в код разных программ, но производятся в пределах всего одной сборки.
Более детальное описание модуля можно найти в руководстве разработчика на сайте проекта , где также есть его исходный код.
2. Графическая оболочка.
Главная задача оболочки – дать пользователю доступ к функционалу модулей. В оболочку как в мозаику, собираются предоставляемые ими графические интерфейсы. Например, web-оболочка (CMF) организует работу с HTML интерфейсами, winForms оболочка – с формами и т.д… Добавление/удаление модулей из оболочки производится исключительно программно, без ручной настройки в куче файлов. По идее это должна быть относительно простая часть архитектуры, которую в принципе не должны затрагивать никакие изменения в прикладных объектных моделях…
Такая архитектура решает сразу три вопроса: корпоративного интерфейса, единой аутентификации и развертывания. Соответственно, все эти вопросы снимаются с прикладных модулей (приложений), тем самым, существенно упрощая их.
Что касается развертывания, то в случае winForms на клиентские машины достаточно поставить только оболочку, а вся прикладная начинка, включая GUI модулей, будет находиться на сервере. Таким образом, даже развертывание и сопровождение приложений winForms ничем не будет отличаться от web-приложений, требуя внесения изменения только в одном месте (на сервере), что упрощает (удешевляет) администрирование системы.
Самое интересное, что стирается принципиальная разница между сайтом, настольным приложением и комплексным решением предприятия, поскольку в основе их всех лежат одни и те же модули. Именно поэтому можно, например, начать с сайта-визитки и постепенно превратить ее в платформу всего предприятия, расширяя конфигурацию, но при этом не меняя архитектуру системы!
Однако, при реализации я наткнулся на большой подводный камень. Хотя такая архитектура оказывается возможной только благодаря универсальности .NET, не смотря на все усилия, мне не удалось вписать в нее ASP.NET. Загвоздка в том, что с одной стороны, ascx контролы и сборки dll, невозможно «оторвать» от aspx страниц – между ними неустранимая жесткая связь, с другой стороны, aspx страницы не возможно произвольно запускать подобно winForms, без предварительной привязки к файловой системе. Попытка натянуть концепцию winForms на web (основная идея ASP.NET) до конца оказалась как-то не доведена.
Следствием этого, при проектировании CMF OpenKit.net, стал вынужденный отказ от того, что считается технологией ASP.NET. Это повлекло как положительные, так и отрицательные моменты. Минусом стало то, что разработчик модулей CMF может использовать встроенные во Framework элементы управления только программно. Плюсом – то, что разработчику теперь можно вообще
Вообще, идея натянуть концепцию winForms на web лично мне представляется довольно сомнительной. В приложениях winForms без компонентного GUI невозможно обойтись в принципе. Но в web, с его HTML, CSS, JavaScript …? Извините. Упрощение малозначимых аспектов, таких, например, как зашивка интерфейсных примитивов в серверные элементы управления и т.п., стоило гигантского усложнения технологии в целом. Впрочем, как оказалось, без знания ASP.NET вполне можно обойтись при разработке web-приложений на .Net. Ни разработчикам модулей, ни администраторам OpenKit, знание ASP.NET не требуется вообще, что, имхо, значительно упростило жизнь.
В итоге имеем: вместо кучи разрозненных приложений написанных неизвестно как и неизвестно на чем – десятки модулей, возможно даже разнотипных, но с одинаковой архитектурой, написанных на одном языке (не считая JavaScript), по одному стандарту и объединенных в одной — двух графических оболочках. Стоимость сопровождения стремится к минимальной, корпоративная информационная система в целом упрощается и, следовательно, становится более надежной и дешевой в сопровождении.
Для небольшой компании это решение может стать недорогой альтернативой ERP и тому подобным системам. Ее разработчики могут своими силами создавать только ту функциональность, которая реально востребована на данном предприятии, не переплачивая за избыточную функциональность и недостаточную гибкость покупных решений с одной стороны и избегая «лоскутной автоматизации» из кучи разношерстных программ с другой.
P.S. Лень: качество, которое заставляет прилагать больше усилий для снижения общих затрат энергии. Она заставляет писать программы, облегчающие труд, и документировать написанное, чтобы вам не пришлось отвечать на лишние вопросы. (Larry Wall, цитирую по Стиву Макконелу «Совершенный код», М. 2005, стр. 810)