1. Рефераты на русском
  2. Информатика
  3. Аспектно-ориентированные методы в управлении информационными потоками баз данных ДП АСУТП

Аспектно-ориентированные методы в управлении информационными потоками баз данных ДП АСУТП

Аспектно-ориентированные методы в управлении информационными потоками баз данных ДП АСУТП
Богданов Николай Константинович, Бұл e-mail спам-боттардан қорғалған, оны қарау үшін Сізде Javascript қосулы болуы керек ,
журнал "Автоматизация в промышленности", №9 - 2003
В классах баз данных ДП АСУТП, также как и в классах программных систем, наблюдается проблема усложнения структуры из-за необходимости поддержки в них различных ограничений и требований к информационной системе в целом. Использование методов аспектно-ориентированного программирования позволяет отделить средства реализации контрактов классов от описываемых ими абстракций сущностей.
Введение. Сущность аспектно-ориентированного программирования
Методы объектно-ориентированного анализа и проектирования позволяют создать модель (архитектуру) информационной системы; провести анализ и создать на его основе модель предметной области. Типизации проектных решений служит широко распространенная концепция шаблонов, эффективные методы анализа и проектирования могут быть оформлены как стратегии.
Однако при разработке программной системы требуется также обеспечить выполнение различных требований к ней. Это могут быть требования к безопасности (необходимость авторизации при проведении транзакций клиент-сервер), качеству обслуживания, синхронизации операций чтения/записи и обеспечению целостности данных и др.
Ранее для специфицирования необходимости обеспечения некоторым классом определенных требований было введено понятие контракта [14]. Однако поддержка любого требования, не относящегося к сущности, описываемой классом, усложняет его структуру, более того, существует ряд требований, общих для многих различных классов или не являющихся функциональными, реализация которых в отдельных классах исключительно затруднена (такие требования называют “пересекающими” (crosscutting)). Требуется введение некоторого дополнительного программного “слоя”, на который было бы возложено выполнение “контрактных обязательств” классов, абстрагирующих сущности предметной области.
Для этого в 1997 г. группой разработчиков из Xerox PARC во главе с Г. Кикзалесом была предложена концепция аспектно-ориентированного программирования (АОП) [13]. Ими было явно введено понятие аспекта, которым является то свойство системы, которое не может быть явно реализовано в виде процедуры. “Аспекты имеют тенденцию не быть элементами функциональной декомпозиции системы, но скорее быть свойствами, которые системно воздействуют на производительность или семантику компонентов”. В этом аспекты противоположны компонентам, “имеющим тенденцию быть единицами функциональной декомпозиции системы”. Цель АОП – “поддержать программиста в четком разделении компонентов и аспектов друг от друга, обеспечивая механизмы, которые сделают возможным абстрагировать их и объединять для получения системы в целом”. (На русском языке концепции и преимущества АОП описаны в [3]).
В работе [11] рассматривается переход от контрактного проектирования к использованию аспектов. Имея в виду под словом “контракт” “спецификацию ограничений, которые должны быть соблюдены некоторой сущностью, запрашивающей услугу от другой сущности”, авторы указывают, что “обычно части проекта, которые реализуют определенный контракт, “рассеяны” (scattered) по всему проекту”. На те же проблемы “рассеивания”, а также на “запутывание” (tangling) структуры классов вследствие необходимости реализации в них механизмов поддержки требований, не связанных с описываемыми ими абстракциями, указывали С. Кларк и Р. Уолкер [8], подчеркивая, что “рассеивание и запутывание имеют негативное влияние на жизненный цикл разработки, с точек зрения возможностей понимания, отладки, развития, повторного использования” (классов и архитектуры системы в целом).
Неотъемлемой частью среды разработки, поддерживающей АО-парадигму, также является инструмент “связывания” (weaving), выполняющий генерацию результирующего программного кода (на этапе компиляции или даже во время выполнения) из двух, в общем случае независимых, проектов: реализующих функциональные требования и вынесенную в аспекты логику.
Для успешного применения любой техники программирования требуется не только ее поддержка языком программирования, но и возможность формализации принятых решений на этапе проектирования. Из этого следует необходимость наличия как минимум графической нотации для записи моделей, как максимум – методологии, формализующей процесс проектирования, и поддержки новой технологии в CASE-средствах разработки.
Обзор методов моделирования аспектов
Как отмечают авторы [16], в то время как существует поддерживающий АО- концепции язык программирования AspectJ [5], отсутствует реализованный язык моделирования, поддерживающий проектирование AspectJ-программ. Предложениям по разработке подобного языка посвящено большое количество работ, представленных на различных конференциях в 1998-2002 гг.
Подавляющее большинство исследователей предлагают основываться на существующем стандарте UML [2] и применить существующие в нем механизмы расширения графической нотации сущностей и отношений (стереотипы, ограничения, помеченные значения) для описания дополнительных концепций AO-проектирования.
Так, в работе [15] предлагается ввести три новых концепции: группы (для целей классификации гетерогенных и распределенных сущностей), пересекающие отношения (позволяющие программисту определить “точки пересечения” аспекта с функциональной программой), аспектные классы (реализующие расширения программы в точках пересечения). Графически это предполагает использование имеющихся в UML элементов: классов и ассоциаций с добавлением стереотипов “group”, “pointcut”, “aspect”. Для методов аспектного класса вводятся стереотипы “before”, “after”, “around”, описывающие момент их вызова по отношению к вызову “пересекаемых” функций, а также предлагается набор правил определения и интерпретации семантики ролей и кратностей для пересекающих отношений.
В [12] рассматривается выделение аспектов в программной системе. Примеры диаграмм в этой работе похожи на приводимые в [15]: аспект рассматривается как диспетчер взаимодействия двух взаимозависимых классов и других, предоставляющих некоторую функциональность. Но, в отличие от [15], в модель явно вводится понятие “точки пересечения”, которую предлагается моделировать как вариант класса, а не как вариант ассоциации, более подробно рассмотрены “точки соединения” – места взаимодействия с аспектом, прерывания/возобновления выполнения основной программы. “Точки соединения могут быть объединены для построения интерфейса аспекта, также как множество интерфейсов в UML могут быть объединены в форму интерфейса класса”. Вводится понятие парных (conjugated) точек соединения, в которых происходит вызов методов с одинаковыми сигнатурами, но направления потока управления противоположны (в которых управление передается аспекту и возвращается им).
С. Кларк и Р. Уолкер предлагают свой вариант нотации [8] для описания аспектов средствами UML. Они предлагают использовать параметризируемые пакеты (что само по себе является непредусмотренным расширением UML) со стереотипом “subject”, поскольку в принципе рассматривают аспекты как элементы субъектно-ориентированного проекта. Внутри пакета могут быть размещены диаграммы классов и взаимодействия, что позволяет графически показать поведение программы после связывания. Такой пакет является в терминологии авторов “композиционным шаблоном”. При этом, “параметризируя проектный субъект и обеспечивая механизм для привязки этих параметров к элементам модели в других проектных субъектах, мы можем определить композицию пересекающего поведения с основным проектом способом, допускающим повторное использование”. Предлагаемая семантика (отношение композиции, расширяемое строкой bind) оперирует классами и методами связываемых субъектов.
В [16] авторы рассматривают моделирование “пересекающих эффектов” отдельно в структуре типов и в поведении некоторой системы. Оригинальность их подхода заключается в предложении использовать параметризируемые, помеченные стереотипом “introduction” кооперации для определении свойств (атрибутов, операций) и отношений каждого из “пересечений” аспектных и обычных классов. Параметр кооперации используется для определения правил связывания (фактически – инстанцирования кооперации и ее встраивания в существующую систему классов). Помимо этих коопераций, в аспектных классах вводятся, независимо от методов, элементы со стереотипами “pointcut” и “advice”: “точки пересечения” и “извещения”, определяющие пересечение логики аспекта и программной системы, и вводящие механизм перехвата управления. Предложенная нотация базируется на концепциях языка AspectJ, но является излишне усложненной.
Разработчики UML указывают, что “На практике для именования класса используют одно или несколько коротких существительных, взятых из словаря моделируемой системы” [2]. Аналогично, в большинстве рассмотренных работ имя аспектного класса является наречием и показывает выполняемую операцию.
Помимо рассмотренных выше четырех работ, предлагающих проработанные, готовые к практическому применению графические нотации, доступно большое количество статей теоретической направленности. Так, в [4] делается попытка формализовать использование средств расширений UML для специфицирования понятий АО-методологии. Для этого используется понятие “профиля” UML – механизма, позволяющего описать правила использования средств расширения языка в некоторой предметной области. Расширяя метамодель UML, авторы определяют набор стереотипов и их приложение к таким элементам метамодели, как класс и ассоциация. Авторы [17] также предлагают расширить метамодель UML для описания аспектных классов и отношений, но основной акцент сделан на предложении основанного на правилах XML языка разметки для описания проектных моделей, в частности, содержащих аспекты. Выгоды его введения обосновываются необходимостью наличия “нейтрального по отношению к приложениям формата” для коммуникации между разработчиками, облегчением повторного использования описаний аспектов, а также их разделением между различными средствами проектирования, связывания, кодогенерации. Комплексным подходом отличается статья известных разработчиков из IBM У. Харрисона, П. Терра и Г. Оссхера [9], в которой они рассматривают способы, какими информация об аспектах может быть отражена на различных диаграммах UML. Здесь же следует упомянуть работы С. Кларк [6, 7], в которых она “представляет подход к разработке систем, базирующийся на объектно-ориентированной модели, но расширяющий ее добавлением новых возможностей декомпозиции”. В докладе [10] представлен прототип автоматизированного средства для преобразования высокоуровневых моделей UML, поддерживающих абстракции АОП, к низкоуровневым детализированным моделям, по которым может быть сгенерирован программный код, т.е. предложено проводить связывание на уровне моделей.
Целью следующей части настоящей статьи является дать представление о применимости АО-методов в обработке информационных потоков в объектно-ориентированной среде, вариантом реализации которой является объектная (объектно-иерархическая) база данных программного комплекса диспетчерского пункта (ДП) АСУТП. При составлении диаграмм мы будем придерживаться нотации, предложенной в [15].
Базы данных ДП АСУТП и задачи управления информационными потоками
Большинство СУБД ДП АСУТП используют модели набора сущностей или иерархическую, а не распространенную в остальных классах систем хранения данных реляционную [1]. Это связано с более высоким быстродействием выборки данных, простотой программной реализации, возможностью отразить в иерархии групп данных структуру автоматизируемого производства, наличием методов относительной адресации. При использовании модели набора сущностей область хранения данных организована линейно, но производится упорядочивание объектов с использованием методов наименования, а логические взаимосвязи между ними с необходимостью приводят к построению некоторого графа. Исходя из этого, в данной работе рассматривается класс так называемых объектно-иерархических СУБД, предоставляющих механизмы упорядочивания хранимых объектов и программный интерфейс манипулирования ими.
База данных ДП АСУТП является как приемником, запрашивающим данные от внешних систем, так и их пассивным источником и таким образом выполняет роль маршрутизатора информационных потоков от систем автоматики и телемеханики к графическим приложениям, системам коммерческого учета и планирования производства, экспертным системам. При этом возникают общие для систем хранения и обработки данных задачи: выполнение функциональных операций; поддержание целостности и эквивалентности реплик данных; а также специализированные – взаимодействие с подсистемой информационного обмена и т.п.
Реализация функциональных операций
Простейший случай использования аспекта – реализация некоторого функционального требования, необходимого разным (не имеющим общего базового) классам. В этом случае аспект становится похож на статический класс-утилиту (utility class), с более четко формализованным в проекте правилом его использования.
Для примера рассмотрим класс, хранящий некоторое значение и его метку времени, имеющий два полиморфных метода записи нового значения: один с передаваемой меткой времени, другой – без нее. Тогда в случае, когда метка времени не передана, необходимо определить текущее время системы и записать его. Для этих целей введем аспектный класс TimeStamping. Его можно показать на диаграмме классов (рис. 1а), при этом мы показываем связанность аспекта не с одним, а с группой классов, объединяет которые в данном случае только необходимость получения значения текущего времени. То, что в принятой нотации группа моделируется как вариант класса, а не пакета UML, позволяет указать для нее методы, подразумевая, что они присутствуют во всех классах, составляющих группу. (Здесь и далее мы задаем имя группы Signal, подчеркивая, что оперируем с множеством классов, хранящих значение некоторого аналогового, дискретного, логического измерения; единицу справочной информации или производную от этих значений величину). Диаграмма взаимодействия (рис. 1б) показывает последовательность выполняемых операций после выполнения связывания (генерации программного кода). При вызове метода SetValue(value) происходит “пересечение”; мы показываем это тем, что на “линии жизни” объекта класса Signal не отмечен фокус управления, который сначала переходит экземпляру аспектного класса, и только потом возвращается им.
 
Рис. 1. Реализация функциональных операций аспектным классом.
Другой пример связывания некоторого аспекта с каждым из некоторого набора объектов в индивидуальности – необходимость отслеживать факт изменения хранимого значения. Перехват вызова метода записи нового значения позволяет установить флаг наличия изменения. Программе-серверу, обрабатывающему запросы внешних систем на получение измененных данных, достаточно будет анализировать состояние данного флага, а не выполнять сравнения хранимых копий предыдущих переданных значений с текущими.
Синхронизация расчетов и изменений
В базах данных ДП АСУТП часто выполняемой операцией является расчет агрегированных значений; например, определение максимального значения из множества или расчет мгновенного расхода жидкости или газа, используя оперативные данные о давлении, его перепаде на диафрагме и температуре, а также ряд заданных нормативных поправочных коэффициентов. В модели мы можем отобразить это, установив ассоциацию один-ко-многим (часто соответствующей отношению контейнер-элемент) и использовав класс-ассоциацию Multiplexer (в который заложена логика преобразования нескольких исходных значений в одно производное). Объекты-элементы являются источниками данных для своего контейнера, в свою очередь, некоторая подсистема опроса систем автоматики является источником оперативных данных для них самих. Эти взаимосвязи можно показать, используя диаграмму классов UML (см. рис. 2).
 
Рис. 2. Типовые отношения классов БД ДП АСУТП.
В системе, управляемой событиями, при изменении хотя бы одного из значений, участвующих в расчете результата и хранящихся в объектах-элементах, должен происходить пересчет формулы и запись нового расчетного значения в объект-контейнер. Рассмотрим для примера расчет некоторого состояния по двум исходным логическим сигналам “открыт”, “закрыт” (см. рис. 3).
 
Рис. 3. Вариант алгоритма перерасчета агрегированного значения.
В рассмотренном алгоритме есть упущение – перерасчет результата происходит при поступлении первого же из изменений. В случае, когда произошло изменение обоих значений, выполнение промежуточного расчета формулы агрегирования с использованием одного нового и одного устаревшего значения избыточно, и, скорее всего, ошибочно. При этом мы не можем заранее утверждать, что всегда при поступлении нового значения одного из сигналов поступает и новое значение другого. Т.о., мы приходим к требованию отслеживать режим поступления обновлений. Для решения этой задачи можно предложить блокировать источником данных передачу сообщений об изменении значений в объектах-элементах на период записи всего множества поступивших обновленных значений. Тогда события об изменении поступят в класс-контейнер после записи обеих новых значений и расчет будет выполнен два раза, но с актуальными данными. (Будучи уверенным, что при поступлении первого же из извещений актуальны оба значения, можно сократить количество перерасчетов до одного).
Однако проблема остается, если источник данных – не один объект, а множество, и на диаграмме мы рассматриваем связь “многие-ко-многим”. (Задача часто возникает при реализации субъектно-ориентированного подхода к проектированию базы данных ДП АСУТП, при котором вводится множество классов, содержащих наборы нормативно-справочных данных, описывающие один и тот же производственный объект при различных точках зрения (принципах декомпозиции предметной области), но которым требуется разделять оперативные данные о его состоянии). Передача (копирование) данных из источников получателям приводит к необходимости поддержания целостности.
Здесь мы приходим к классической ситуации введения аспекта – реализация в отдельном классе-источнике или получателе данных алгоритма отслеживания взаимодействия других пар объектов и синхронизации с ними исключительно затруднена. Цель – обеспечить синхронизацию обновления данных; желаемое поведение аспекта – реализовать “конвейерную передачу” обновлений по уровням иерархии и между поддеревьями БД.
 
Рис. 4. Введение аспекта TransferSynchronizing для управления передачей данных.
Сначала определим “точку пересечения”. Она одна – аспект перехватывает управление при попытке выполнения каким-либо из объектов-источников записи одного или нескольких новых значений; блокирует обработку новых значений в объектах-получателях, дает завершиться перехваченным методам SetValue(…), после чего ожидает в течение заданного интервала времени выполнения аналогичных действий другими объектами-источниками (см. рис. 4). По истечении времени ожидания происходит разблокирование всех объектов-получателей, в которые были записаны новые значения. Данная логика показана на рис. 5; отношение “многие-ко-многим” классов-источников и получателей данных рассматривается как множество отношений “один-ко-многим” их экземпляров. (Мы рассматриваем множества объектов – экземпляров некоторых классов, объединенные в две группы по их роли в частном информационном взаимодействии: источников и получателей данных; стереотипы “source” и “receiver” являются производными от базового “group”. Имена групп (при отличии стереотипа) совпадают, что подчеркивает единообразие входящих в них классов).
 
Рис. 5. Выполнение передачи данных при введенном аспекте TransferSynchronizing.
Отметим, что не требуется вводить точку пересечения с классом-получателем данных, поскольку нет необходимости перехватывать все выполняемые вызовы изменения данных в нем, а также использование стереотипа “around” для метода OnSetValue() аспектного класса: часть служебных операций выполняется до исполнения вызова SetValue(…), часть – после. Предложенное решение все еще содержит ряд недостатков: объект-источник зависим от реализации объекта-получателя; введение периодов ожидания плохо согласуется с событийной моделью; объект-получатель должен проверять попадание разности нового и предыдущего значений в “зону нечувствительности”; его структура усложняется средствами поддержки блокировок. Можно предложить вариант, свободный и от данных недостатков.
Для этого определим, что у каждой группы есть менеджер – экземпляр аспектного класса, выполняющий контракты каждого из классов группы, в т.ч. и вызов метода SetValue(…) для записи измененного значения в класс-получатель. Это позволяет также выполнять операции блокирования/разблокирования только по отношению к этому аспектному классу. На него же может быть переложено выполнение проверки “существенности” отличия нового значения от текущего в объекте. Тогда желаемое поведение, реализующее транзакционный подход к передаче массива данных, можно отобразить в виде :диаграммы (см. рис. 6). (На диаграмме показано взаимодействие только двух групп, хотя, разумеется, объекты и даже единственный объект группы-источника может являться записывать данные в несколько объектов, в т.ч. принадлежащих различным группам.) Поскольку, как отмечалось выше, каждая из групп может играть роль как источника, так и получателя данных, то на диаграмме классов достаточно показать связь аспекта и одной группы (см. рис. 7а).
Диаграмма, показывающая внутреннюю логику аспекта при разблокировании, приведена на рис. 7б. Отметим, что возможно одновременная блокировка группы несколькими менеджерами групп-источников: запись различных данных в один и тот же объект в любом случае не имеет смысла, а одновременная запись значений в различные объекты заблокированной группы несколькими источниками не приводит ни к каким отрицательным последствиям.
 
Рис. 6. Выполнение передачи данных при введенном аспекте GroupManager.
 
 
Рис. 7. Структура и внутренняя логика аспектного класса GroupManager.
Взаимодействие с подсистемой информационного обмена
Взаимодействие “объект БД – модуль информационного обмена с внешними системами (далее – сканирования)” в ряде баз данных ДП АСУТП настраивается с использованием “списка сигналов”: в табличной форме объединяются индивидуальные параметры опроса каждого сигнала (тип данных, адрес в контроллере, периоды периодических опросов значений и изменений и т.п.). В других системах данная параметрическая информация сохраняется в самом объекте БД. Оба этих подхода обладают тем недостатком, что не используют естественно напрашивающую предположение об одинаковости параметров (коммуникационных, преобразования “сырых” данных) для однотипных объектов БД, т.е. экземпляров одного класса. Поэтому в данном случае аспектный класс используется как расширитель структуры класса БД (это отмечено отношением зависимости со стереотипом “extend”): он содержит таблицы соответствий класса и параметров сканирования, класса и правил преобразования полученных данных, а также список соответствий индивидуальных объектов и адресов во внешней системе (или правила получения адресов по имени объектов).
С другой стороны, от различных модулей сканирования требуется обеспечивать однотипное поведение при определенных событиях; например, качество значений всех объектов БД, получающих данные от внешней системы, с которой потеряна связь, должно быть установлено в “недостоверное”. Аспектный класс “пересекает” операции модуля сканирования, результаты которых влияют на прочие объекты БД, и реализует единообразную логику для различных приложений информационного обмена.
Заключение
Иерархия классов отражает уровни абстракции сущностей предметной области, иерархия объектов (в БД ДП АСУТП) является информационной моделью автоматизируемого производства, технологического процесса. Для отражения различных точек зрения возможно разделение классов и построение нескольких подмоделей, используя различные принципы декомпозиции. Применение методов аспектно-ориентированного программирования позволяет отделить средства реализации контрактов каждого из классов (механизмов поддержки в них различных ограничений и требований к информационной системе в целом) от описываемых ими абстракций сущностей, за счет чего повысить степень надежности БД, производительность обработки и передачи данных, возможность повторного использования проектных решений.
 
Рис. 8. Настройка взаимодействия и обработка событий подсистемы информационного обмена.
Литература
1. Богданов Н.К. Тиражируемые программные комплексы для создания АСУТП. // Промышленные АСУ и контроллеры. 2000. №12. – С. 35-39
2. Буч Г., Рамбо Д., Джекобсон А. Язык UML. Руководство пользователя. М.: ДМК Пресс, 2000. – 432 с.
3. Шукла Д., Селлз С.Ф.К. АОП: Более эффективная инкапсуляция и повторное использование кода. // MSDN Magazine/Русская редакция. 2002. Спецвыпуск №1.
4. Aldawud, O., Elrad, T., Bader, A. A UML Profile for Aspect-Oriented Modeling. In proc. of Aspect-Oriented Programming Workshop at OOPSLA, 2001.
5. AspectJ Home Page. http://www.aspectj.org
6. Clarke, S. Composing Design Models: An Extension to the UML. In proc. of International Conference on the UML, 2000, pp. 338-352.
7. Clarke, S. Extending Standard UML with Model Composition Semantics. // Science of Computer Programming. Vol. 44, Issue 1 (July 2002), pp. 71-100
8. Clarke, S., Walker, R. Composition Patterns: An Approach to Designing Reusable Aspects. In proc. of ICSE 2001.
9. Harrison, W., Tarr, P., Ossher, H. A Position On Considerations in UML Design of Aspects. In proc. of Workshop on Aspect-Oriented Modeling with UML at AOSD, 2002.
10. Ho, W., Pennaneac'h, F., Jezequel, J., Plouzeau, N. Aspect-Oriented Design with the UML. In proc. of Multi-Dimensional Separation of Concerns Workshop at ICSE, 2000, pp. 60-64
11. Jezequel, J., Plouzeau, N., Weis, T., Geihs, K. From Contracts to Aspects in UML Designs. In proc. of Workshop on Aspect-Oriented Modeling with UML at AOSD, 2002.
12. Kande, M.M., Kienzle, J., Strohmeier, A. From AOP to UML - A Bottom-Up Approach. In proc. of Workshop on Aspect-Oriented Modeling with UML at AOSD, 2002.
13. Kiczales, G., Lamping, J., Mendhekar, A., Maeda, C., Lopes, C., Loingtier, J., Irwin, J. Aspect-Oriented Programming. In proc. of ECOOP, 1997, LNCS 1241, pp. 220-242
14. Meyer, B. Object-Oriented Software Construction. New-York, NY: Prentice Hall, 1988.
15. Pawlak, R., Duchien, L., Florin, G., Legond-Aubry, F., Seinturier, L., Martelli, L. A UML Notation for Aspect-Oriented Software Design. In proc. of Workshop on Aspect-Oriented Modeling with UML at AOSD, 2002.
16. Stein, D., Hanenberg, S., Unland, R. Designing Aspect-Oriented Crosscutting in UML. In proc. of Workshop on Aspect-Oriented Modeling with UML at AOSD, 2002.
17. Suzuki, J., Yamamoto, Y. Extending UML with Aspects: Aspect Support in the Design Phase. In proc. of Aspect-Oriented Programming Workshop at ECOOP, 1999.
Интернет
1. Workshop on Aspect-Oriented Modeling with UML at AOSD’02.
http://lglwww.epfl.ch/workshops/aosd-uml/papers.html
2. Workshop on Multi-Dimensional Separation of Concerns (ICSE 2000) http://www.research.ibm.com/hyperspace/workshops/icse2000/papers-index.htm
3. Aspect-Oriented Software Development http://www.aosd.net/
4. Aspect-Oriented Programming http://www.c2.com/cgi/wiki?AspectOrientedProgramming

 

  Рефераты на русском языке - Информатика


Яндекс.Метрика