Аспектно-ориентированное программирование: различия между версиями

Содержимое удалено Содержимое добавлено
м →‎История: оформление
Нет описания правки
Строка 1:
{{wikipedia|Аспектно-ориентированнаяориентированное разработка программного обеспеченияпрограммирование}}
 
'''Аспе́ктно-ориенти́рованное программи́рование''' ({{lang-en|AOP}}) — это новаяметодика технология,программирования позволяющаяв программистамрамках компоновать[[Объектно-ориентированное программыпрограммирование|классовой изпарадигмы]], взаимноосновывающая пересекающихсяна блоковпонятии (''crosscutting concernsаспекта''). AOP вводитблока вкода, действиеинкапсулирующего аспектысквозное (''aspects'').поведение Онив инкапсулируют особенности поведения взаимно влияющих друг на другасоставе классов в составеи повторно используемых модулей.
 
В последней версии [[w:AspectJ|AspectJ]] от Xerox PARC [[w:Java|Java-разработчики]] могут пользоваться всеми преимуществами модульной компоновки, предлагаемыми AOP. В этой статье читатель познакомится с [[w:AspectJ|AspectJ]] и интересными возможностями его использования в проектировании.
 
== История ==
Аспектно-ориентированное программирование «выросло» из осознания того, что в типовых программах на объектно-ориентированных языках часто представлено поведение, которое не вмещается естественно в один или даже в несколько тесно связанных программных модулей. Пионеры аспектного подхода определиливвели такоетермин поведение термином«пересечение» '(''crosscutting''',) посколькудля приобозначения этомповедения пересекаютсякода, другпри скотором другомпересекаются ответственности разработчиков программных модулей. В объектно-ориентированном программировании, например, естественной единицей модульности является класс, а отношение«секущее» ''crosscutting''свойство охватывает несколько классов. ОбычноЧасто отношение ''crosscutting''пересечение встречается при организации журналовжурналирования работы приложения (логирование)приложений, контекстно- зависимой обработке ошибок, оптимизации выполнения программ, а также в шаблонах проектирования.
 
Если вы когда-нибудь работали над кодом ссо сквозной crosscutting-отношениемфункциональностью, вам известны проблемы, связанные с ограничением модульности. Поскольку crosscutting-«поперечное» поведение реализуется разрозненно, разработчики находят такое поведение затруднительным в осмысливании, реализации и изменении. Код для ведения журналов, например, переплетается с кодом, отвечающим в основном за что-либо другое. В зависимости от масштаба и сложности crosscutting-отношения степень запутанности может быть более или менее значительной.
Изменение политики регистрации активности приложения может потребовать многих сотен правок — тяжелейшая, если, вообще, выполнимая задача. С другой стороны известен пример следующего рода:
 
[?]
 
:Для оптимизации эффективности некую программу переписали — при этом из 768-строковой она превратилась в 35213 строк. С применением аспектно-ориентированной технологии этот код уменьшился до размера в 1039 строк, почти полностью сохранив при этом эффективность.
Строка 15:
AOP дополняет объектно-ориентированное программирование, обогащая его другим типом модульности, который позволяет локализовать код реализации crosscutting логики в одном модуле. Такие модули обозначаются термином аспекты, от аспектно-ориентированного программирования. За счет отделения аспектно-ориентированного кода работа с crosscutting- отношениями упрощается. Аспекты в системе могут изменяться, вставляться, удаляться на этапе компиляции и, более того, повторно использоваться.
 
==AspectJ==
== Примеры ==
Чтобы лучше почувствовать особенности аспектно-ориентированного программирования, рассмотрим [[w:AspectJ]] — аспектно-ориентированное расширение [[w:Java|JavaДжавы]], предложенное [[w:Xerox PARC|Xerox PARC]]. ВПредставим качествеего примерана рассмотримпримере фрагмент кода, предназначенныйпрограммы для регистрациижурналирования событий в log-файле, реализованныйреализованной на AspectJ. Этот пример взят из системы с открытым кодом Cactus, упрощающей тестирование JavaДжава-компонентов на стороне сервера. Каркас Cactus разработан для поддержки процесса отладки с помощью трассировки вызовов всех методов. Версия 1.2 Cactus была написана без [[w:AspectJ|AspectJ]]. Поэтому большинство методов выглядели, как показано ниже.
 
<source lang="java">
Строка 28:
</source>
 
Каждому разработчику, в рамках соглашений по созданию проектов, предлагалось включать log-вызовы <code>logger</code> в начало и в конец каждого метода. Кроме того, рекомендовалось заносить в logжурнал значения параметров каждого метода. Следование этим соглашениям требовало существенных усилий со стороны разработчика. Так в версии Cactus 1.2 содержится около 80 различных регистрационных вызовов, охватывающих 15 классов. В версии 1.3 эти 80 вызовов были заменены одним аспектом, который автоматически регистрирует и параметры, и возвращаемые значения наряду с входами и выходами метода. Упрощенная версия этого аспекта (опущена регистрация параметра и возвращаемого значения) представлена ниже:
 
<source lang="java">
Строка 53:
Проанализируем этот пример и посмотрим, какие действия осуществляет аспект. Первое, на что нужно обратить внимание — это объявление аспекта. Оно подобно объявлению класса и, так же как класс, определяет тип Java. Кроме того, аспект содержит конструкции ''pointcut'' и ''advice''.
 
=== Конструкция ''pointcut'' и точки соединения (''joint points'') ===
Прежде всего, рассмотрим, что представляет собой '''join point''' (точка соединения). Точки соединения — это однозначно определенные точки при выполнении программы. Так под точками соединения в AspectJ подразумеваются: вызовы методов, точки обращения к членам класса и исполнение блоков обработчиков исключений и т. д. Точки соединения могут, в свою очередь, содержать другие точки соединения. Например, результат вызова метода может передаваться каким-то другим методам. А pointcut является языковой конструкцией, которая отбирает множество точек соединения на основании определенного критерия. В приведенном выше примере первый pointcut под именем publicMethods выбирает исполнения всех public методов в пакете org.apache.cactus. Подобно int, который является базовым типом Java, Execution является базовым pointcut. Он выбирает исполнения методов, соответствующих сигнатуре, заданной в скобках. Для сигнатур допустимо включение символов шаблонов: в приведенном примере оба pointcut-а содержат несколько таких символов. Второй pointcut с именем logObjectCalls выбирает все исполнения методов в классе Logger. Третий pointcut loggableCalls, объединяет два предыдущих, используя && !, что означает выбор всех public методов из org.apache.cactus за исключением таковых в классе Logger. (Регистрация log методов привела бы в результате к бесконечной рекурсии).
 
Строка 103:
</source>
 
=== Программирование в AspectJ ===
Теперь, когда мы представляем себе, что такое код аспекта, зададим вопрос «Как заставить приведенный выше код работать?».
 
Строка 113:
Существенное ограничение текущей версии AspectJ состоит в том, что ее компилятор может вводить аспекты только в код, для которого есть исходный текст. Иными словами, невозможно использовать ajc для включения advice в уже откомпилированные классы. Разработчики AspectJ представляют это ограничение как временное, и на Web-сайте AspectJ можно найти подтверждение того, что в будущей версия (официально — версия 2.0) будут допустимы модификации на уровне байт-кода.
 
=== Обзор возможностей AspectJ ===
==== Introduction как средство воздействия на структуру класса ====
Pointcuts и advice позволяют влиять на динамику выполнения программы, ''introduction'' предоставляет аспектам возможность модифицировать статическую структуру программы. Используя ''introduction'', аспекты могут добавлять новые методы и переменные в классы, объявлять класс как реализацию интерфейса, устанавливать или отменять проверку исключений.
 
Строка 141:
Мы объявляем внедряемые методы и переменные члены класса почти так же как для обычных членов класса, за исключением того, что нужно уточнять, для какого класса мы их определяем (отсюда ''ValueObject.timestamp'').
 
===== Наследование в стиле mix-in =====
AspectJ позволяет добавлять члены в интерфейсы (аналогично добавлению в классы), что относится к наследованию в стиле mix-in a la C++.
Если мы хотим ввести в общее употребление аспект, рассмотренный в предыдущем разделе, таким образом, чтобы стало возможным многократное использование кода timestamp для множества объектов, следует определить интерфейс с именем ''TimestampedObject'', и далее использовать ''introduction'' для добавления тех же самых членов и переменных в интерфейс вместо конкретного класса:
Строка 189:
''Pointcut this()'' определяет все точки соединения, где исполняемый в настоящее время объект имеет тип, заданный в скобках. Несколько других типов значений могут быть связаны с аргументами advice, такие как аргументы метода, исключения при исполнении метода и результат вызова метода.
 
==== Настраиваемые ошибки компиляции ====
Возможность настройки ошибок компиляции можно считать одной из самых дерзких особенностей AspectJ. Предположим, мы хотим изолировать подсистему так, чтобы клиентскому коду пришлось бы использовать некую промежуточную функциональную обвязку вместо прямого обращения к рабочим объектам (такая ситуация имеет место в шаблоне проектирования Facade). Используя синтаксис declare error или declare warning, можно настроить реакцию компилятора ajc на появление точки соединения в коде:
 
Строка 203:
Pointcut within подобен this() за исключением того, что ajc обнаруживает его только на этапе компиляции (большинство pointcut могут срабатывать на основе информации времени выполнения).
 
==== Обработка ошибок ====
Есть множество обрабатываемых исключений в языке [[w:Java]]. Зачастую создаются такие методы, которые наверняка не должны вызывать исключений, и, возможно, они не будут происходить ни у кого из потенциальных пользователей метода. Мы не призываем игнорировать возможные исключения, но тяжело отслеживать присутствие исключений во всех вызовах метода. Есть разные искусные способы использования блоков try/catch, чтобы все-таки решить эту задачу, но самый элегантный — это declare soft в AspectJ. Рассмотрим пример работы с базой данных:
 
Строка 252:
''Pointcut'' и ''advice'' закрывают соединение и оператор после каждого метода из класса SQLAccess, в любом случае, приводит ли он к исключению или завершается нормально. Возможно, это расточительно — использовать обрабатывающий ошибки аспект для одного метода, но если есть намерения добавить некоторые другие методы, использующие соединение и оператор, то такая методика обработки ошибок применялась бы и к ним. Такое автоматическое применение аспектов к новому коду является одним из ключевых проявлений устойчивости AOP: авторам нового кода не нужно знать о взаимно пересекающемся поведении для того, чтобы принимать в нем участие.
 
=== Инструментальная поддержка ===
Xerox подготовил [[w:AspectJ|AspectJ]] к использованию под '''Mozilla Public License''', что является хорошей новостью для энтузиастов [[w:Открытый исходный код|открытого кода]]. Это обрадует и тех, кто собирается остановить свой выбор на AspectJ в ближайшем будущем, поскольку продукт ничего не стоит, и при этом для пользователя сохраняется гарантированная возможность проверки исходного кода.
Использование открытого кода означает также, что исходный код AspectJ был предметом серьезного общественного обсуждения, прежде чем появиться на рынке.
Строка 258:
Одним из наиболее важных инструментов в релизе AspectJ является графический структурный браузер, который позволяет быстро увидеть, как аспекты взаимодействуют с другими компонентами системы. Этот структурный браузер доступен и как ''plug-in'' для популярных [[w:Среда разработки программного обеспечения|IDE]], и как самостоятельное средство. Структурный графический браузер для навигации и, в частности, чтобы определить, какие методы ''AutoLog'' используются в конструкции ''advice''. В дополнение к структурному браузеру и основному компилятору можно загрузить с Web-сайта AspectJ отладчик для аспектов, инструмент ''javadoc'', ''Ant task'' и ''plug-in Emacs''.
 
=== Заключение ===
Стоит ли использовать AspectJ? Гради Буч описывает аспектно-ориентированное программирование как одно из трех направлений, которые в совокупности знаменуют начало фундаментальных изменений в способах проектирования и написания программного обеспечения (см. статью [http://www.sdmagazine.com/documents/s=843/sdm0107i/0107i.htm Through the Looking Glass]). С ним вполне можно согласиться. Сфера действия AOP охватывает пространство проблем, непосильных для объектно-ориентированных и процедурных языков. Оно предлагает элегантные пути для реализации задач, решение которых сдерживалось из-за фундаментальных ограничений программирования. Было бы справедливо сказать, что AOP представляет собой одну из самых мощных абстракций в программировании с момента появления объектов.
 
Строка 265:
Способность AspectJ к «модулированию немодулируемого» должна найти достойное применение. Если вы пока не готовы использовать AspectJ в полном объеме для разработки, его на первых порах можно легко применить в отладке, не упуская благоприятных возможностей, предоставляемых этим расширением.
 
=== Ссылки на ресурсы Internet ===
* [http://www.aspectj.org AspectJ.org] — официальный ресурс AspectJ
* [http://www.aosd.net aosd.net] — портал поклонников аспектно-ориентированного программирования
 
==[[Лисп]]==
{{Эпиграф|В Лиспе, если охота аспектно-ориентированного программирования, нужно лишь настругать немного макросов, и готово. В Джаве, нужен Грегор Кичалес, создающий новую фирму, и месяцы и годы попыток заставить всё работать.}}
{{Подпись|— [http://www.norvig.com/ Петер Норвиг]}}
 
[…]
 
[[Категория:Программирование]]
[[Категория:Java]]