Введение

Парадигма программирования

В вычислительной технике, аспектоориентированное программирование (AOP) — это парадигма программирования, направленная на повышение модульности за счет разделения сквозных задач. Это достигается путем добавления поведения к существующему коду (совета) без его изменения, а вместо этого отдельным указанием, какой код модифицируется с помощью спецификации "pointcut", например, "регистрировать все вызовы функций, имя которых начинается с 'set'". Это позволяет добавлять в программу поведение, не являющееся центральным для бизнес-логики (например, ведение журналов), не усложняя код основных функций. AOP включает в себя методы и инструменты программирования, поддерживающие модулизацию задач на уровне исходного кода, в то время как разработка программного обеспечения, ориентированного на аспекты, представляет собой целую инженерную дисциплину. Аспектоориентированное программирование предполагает разбивку логики программы на согласованные области функциональности (так называемые задачи). Почти все парадигмы программирования поддерживают определенный уровень группировки и инкапсуляции задач в отдельные, независимые сущности, предоставляя абстракции (например, функции, процедуры, модули, классы, методы), которые могут быть использованы для реализации, абстрагирования и компоновки этих задач. Некоторые задачи "пронизывают" несколько абстракций в программе и не поддаются этим формам реализации. Эти задачи называются сквозными или горизонтальными. Ведение журналов является примером сквозной задачи, поскольку стратегия ведения журналов должна затрагивать каждую часть системы, подлежащую журналированию. Таким образом, ведение журналов пронизывает все классы и методы, подлежащие журналированию. Все реализации AOP имеют сквозные выражения, которые инкапсулируют каждую задачу в одном месте. Разница между реализациями заключается в мощности, безопасности и удобстве использования предоставляемых конструкций. Например, перехватчики, которые задают методы для выражения ограниченной формы сквозной обработки, без существенной поддержки типобезопасности или отладки. AspectJ имеет ряд таких выражений и инкапсулирует их в специальный класс, называемый аспектом. Например, аспект может изменять поведение базового кода (неаспектной части программы) путем применения советов (дополнительного поведения) в различных точках соединения (точках в программе), указанных в квантификации или запросе, называемом pointcut (который определяет, соответствует ли данная точка соединения критериям). Аспект также может вносить бинарно совместимые структурные изменения в другие классы, такие как добавление членов или родительских классов.

История

AOP имеет несколько прямых предшественников: рефлексию и метаобъектные протоколы, предметно-ориентированное программирование, композиционные фильтры и адаптивное программирование. Грегор Кицалес и его коллеги из Xerox PARC разработали явную концепцию AOP и затем создали расширение AspectJ для Java. Исследовательская группа IBM предпочла инструментальный подход разработке нового языка и в 2001 году предложила Hyper/J и среду манипулирования аспектами, которые не получили широкого распространения. В примерах, представленных в этой статье, используется AspectJ. Microsoft Transaction Server считается первым крупным применением AOP, за которым последовала технология Enterprise JavaBeans.

Модели точек стыковки

Консультативный компонент языка, ориентированного на аспекты, определяет модель точек соединения (JPM). JPM определяет три вещи:

Когда совет может быть выполнен. Эти точки называются точками соединения, поскольку они представляют собой места в работающей программе, где дополнительное поведение может быть полезно добавлено. Чтобы быть полезной, точка соединения должна быть доступна и понятна обычному программисту. Она также должна быть стабильной при несущественных изменениях программы для обеспечения стабильности аспекта. Многие реализации AOP поддерживают выполнение методов и обращения к полям в качестве точек соединения. Способ указания (или определения) точек соединения называется точечным выражением (pointcut). Точечные выражения определяют, соответствует ли данная точка соединения заданным критериям. Большинство полезных языков точечных выражений используют синтаксис, аналогичный базовому языку (например, AspectJ использует сигнатуры Java) и обеспечивают возможность повторного использования посредством именования и комбинирования. Также необходим способ указания кода, который будет выполняться в точке соединения. AspectJ называет это советом и может выполнять его до, после и вместо точки соединения. Некоторые реализации также поддерживают определение метода в аспекте для другого класса. Модели точек соединения можно сравнивать по следующим критериям: набор доступных точек соединения, способ их указания, разрешенные операции в точках соединения и структурные улучшения, которые можно выразить.

Другие модели потенциальных точек слияния

Есть и другие виды JPM. Все языки консультаций можно определить в терминах их JPM. Например, гипотетический аспектный язык для UML может иметь следующий JPM:

Точки соединения – это все элементы модели. Точки среза – это любое булево выражение, комбинирующее элементы модели. Средства воздействия в этих точках – это визуализация всех найденных точек соединения.

Сравнение с другими парадигмами программирования

Аспекты возникли из объектно-ориентированного и рефлексивного программирования. Языки AOP обладают функциональностью, аналогичной, но более ограниченной, чем протоколы метаобъектов. Аспекты тесно связаны с такими концепциями программирования, как субъекты, миксины и делегирование. Другие способы использования парадигмы аспектно-ориентированного программирования включают фильтры композиции и подход гиперсрезов. Разработчики использовали формы перехвата и патчей для динамической диспетчеризации, напоминающие некоторые методы реализации AOP, еще по крайней мере с 1970-х годов, но эти методы не обладали той семантикой, которую спецификации сквозной функциональности предоставляют в едином месте. Дизайнеры рассматривали альтернативные способы разделения кода, такие как частичные типы в C#, но этим подходам не хватает механизма квантификации, позволяющего охватить несколько точек соединения кода одним декларативным выражением. Хотя это может показаться не связанным, в тестировании использование моков или заглушек требует применения техник AOP, таких как advice вокруг. В этом случае взаимодействующие объекты, для целей тестирования, представляют собой сквозную проблему. Поэтому различные фреймворки для создания моков предоставляют соответствующие возможности. Например, процесс вызывает сервис для получения суммы баланса. При тестировании процесса неважно, откуда берется эта сумма, а только то, что процесс использует баланс в соответствии с требованиями.