Основы проектирования корпоративных систем - Сергей Зыков
Шрифт:
Интервал:
Закладка:
При этом важным понятием является домен приложения, ранее говорилось о доменах в связи с технологией Remoting и другими технологиями, которые осуществляют создание и поддержку распределенных приложений в среде. NET, в частности WCF, веб-сервисы. Речь идет о логическом контейнере сборок, который применяется для осуществления локализации или изоляции приложения внутри процесса. Какие важные свойства доменов нужно запомнить, говоря о компонентных приложениях? Во-первых, что домены изолированы друг от друга. CLR может осуществлять загрузку и выгрузку домена со всеми сборками, которые участвуют в этих доменах. Возможно осуществление дополнительных конфигурационных настроек и надстроек, связанных с обеспечением безопасности, применительно к каждому из доменов. Технологии маршаллинга, о которых уже упоминалось, – это передача данных между границами доменов или процессов. При этом такой обмен данными осуществляется в безопасном режиме. Известно, что существует маршаллинг по имени, по значению, по ссылке. Кроме того, доменная модель поддержана на уровне. NET Framework, существует компонентная модель, в которой основными элементами являются сборки. А если берется более широкая модель COM-объектов, в частности, как это, скажем, происходит при работе с офисными или другими приложениями, что используются внутренние механизмы, которые называются COM InterOP и обеспечивают интероперабельность, взаимодействие. NET-объектов с COM-объектами, по сути, NET-сборок с COM-объектами, и наоборот. При этом не требуется регистрации компонентов в реестре Windows, если речь идет о. NET-приложении.
Что касается видов сборок, выделяются частные и общие, Private и Shared или разделяемые сборки. Если речь идет о частной сборке, то тот набор типов, который в ней описан, может быть использован только приложениями, в состав которых входит эта сборка. Если речь идет о сборках общего доступа, что они могут использоваться любым количеством приложений, не обязательно ограниченным на клиентском компьютере. Ранее говорилось о взаимодействии. NET-компонентов, т. е. по сути – сборок и COM-объектов – более общего класса компонентов. Взаимодействие этих компонентов в среде CLR реализовано на основе механизма оберток или временных оболочек Runtime Callable Wrapper (RCW), который инкапсулирует различия между управляемым и неуправляемым кодом.
NET-сборка содержит управляемый код, COM-объект, вообще говоря, содержит код неуправляемый. Такого рода оболочки или обертки позволяют управлять жизненным циклом COM-объектов, передавать вызовы между управляемым и неуправляемым кодами и осуществлять преобразование параметров методов. Во многом этот подход схож с концепцией веб-сервисов и реализацией сервис-ориентированной архитектуры. То есть более общего расширения, когда можно строить взаимодействующие компоненты, не только созданные под управлением. NET для CLR, но и сторонние компоненты, взаимодействующие по стандартным протоколам типа SOAP и осуществляющие взаимодействие между компонентами корпоративных приложений, построенных на основе той или компонентной модели.
При вызове COM-клиента. NET-среда CLR создает всего одну оболочку, всего одну обертку, независимо от количества ссылок на объект. Это происходит для того, чтобы все обращения к объекту осуществлялись централизованно, единообразно, только посредством этой оболочки. Кроме того, на основе метаданных создаются вызываемый объект и оболочка или обертка для возврата данных, т. е. для передачи данных обратно от. NET-среды COM-клиенту.
Обертка осуществляет управление сборкой мусора на уровне среды CLR. При этом разработка существенно упрощается, поскольку от программиста не требуется слежение за динамической памятью и своевременное ее освобождение. Содержимое сборки можно посмотреть, запустив программу, которая называется ILDAsm.exe (Intermediate Language Dis Assembler). Это достаточно интересная программа с точки зрения ее функционирования, потому что она является очень мощной и восстанавливает код фактически с точностью до идентификаторов. Если говорить об обычном дизассмеблере, то, как правило, он вместо идентификаторов вставляет какие-то свои, системные переменные, и код достаточно тяжело читать. Если для примера рассмотреть простое консольное приложение на C#, которое выводит единственное сообщение на экран – «Hello World», то видно, что оно имеет очень много идентификаторов. Вот SimpleApp – пространство имен, класс у нас называется Class1 и никак иначе, и использует стандартную функцию WriteLine внутри стандартного метода Main.
Посмотрим, как работает ILDAsm, если его запустить применительно к сборке, которая получена из этого приложения. Восстанавливается весь вид сборки, при этом в MSIL-коде присутствуют все идентификаторы, которые были в C#. Идентификатор Class1: существует вызов стандартной процедуры WriteLine с использованием единственного параметра String, при этом используется пространство имен System, и внутри используется класс Console, его метод WriteLine. Несколько иначе выставляются обозначения, но этот текст очень легко читается, несмотря на то, что это ассемблер. Он загружает строчку в память, вызывает функцию и осуществляет возврат управления из этой процедуры.
На уровень выше используется частный метод, он сохраняет все атрибуты, связанные с доступом, все идентификаторы доступа и представленные в графическом виде метаданные сборки. Это манифест, т. е. метаданные сборки, которые получены из приложения SimpleApp.exe, т. е. из EXE-файла, который, казалось бы, не должен был содержать ничего указывающего на идентификаторы, но восстанавливаются название приложения, имя Class1 и абсолютно все метаданные, все ресурсы.
Кроме того, существует средство Reflection, которое позволяет восстановить по DLL или по EXE-файлу, т. е. по сборке, собственно код. И код, который видно на экране, – фактически наш исходный код, написанный на C#. Если использовать средство Reflection, можно восстановить код из exe-файла фактически в том виде, в котором он был написан автором. Это таит в себе неприятности и опасности, поскольку надо каким-то образом защищать авторское право и код от просмотра. Существует средство, которое называется Obfuscator, или запутыватель. Оно внедряет ряд переходов, разбивает процедуры на более мелкие, в общем меняет структуру кода таким образом, чтобы было сложно, глядя на него, сказать, какой именно метод и из какого именно места программы вызывается. Таким образом, Microsoft борется с возможностью восстановления прямого кода. Но нужно сказать, что Reflection – очень сильное средство, если не защищать код специальным образом.
Подводя итог, следует отметить, что компонентный подход является развитием объектно-ориентированного подхода к разработке программных систем и имеет ряд важных преимуществ. Во-первых, это снижение стоимости разработки программного обеспечения, прежде всего прикладного, в данном случае корпоративных систем. Во-вторых, появляется больше возможностей для повторного и многократного использования кода. Тот код, который создан в виде сборок, имеет стандартные интерфейсы, реализует стандартные функции, и если проектирование ведется целенаправленно, с целью обеспечить максимальную долю многократно используемого кода, то композиция компонентов будет произведена таким образом, что эти самые компоненты, эти самые сборки пригодятся разработчикам при использовании в новых проектах. При этом, естественно, если потребуется коррекция кода программных продуктов, которые были разработаны, во-первых, можно ограничиться крайне незначительным изменением, в идеале – одной сборки или небольшого количества сборок, которые взаимосвязаны или связаны с той функциональностью, которая меняется или дорабатывается в рамках нового технического задания или нового соглашения, разработанного с заказчиком. И во-вторых, концепция компонента является универсальной и не зависит от подхода к разработке программных систем. Неважно, создается ли код на объектно-ориентированном или на функциональном языке, в рамках. NET с точки зрения CLR то, что разработано, есть компонент. Будь это dll библиотека или exe-модуль. Важно, что этот компонент можно переработать, если нужно переработать только его или только несколько компонентов, а остальной продукт оставить без изменений. Используя стандартные интерфейсы, можно переработать эти компоненты на любых языках программирования, или просто выбросить одни компоненты и заменить их другими, используя те языки программирования, которые поддерживаются. NET, а прочие компоненты оставить без изменения и таким образом обеспечить экономичную разработку, высокий процент повторного использования и хорошую сопровождаемость. То есть вносить изменения быстро и в ограниченные фрагменты кода.