2. Аспектно-ориентированное подход (АОП) — методология
программирования, основанная на идее разделения
функциональности для улучшения разбиения программы на
модули.
АОП предлагает языковые средства, позволяющие
выделять сквозную функциональность в отдельные модули,
и таким образом упрощать работу с компонентами
программной системы, и снижать сложность системы в
целом.
Методология АОП была предложена группой инженеров
исследовательского центра Xerox PARC под руководством
Грегора Кичалеса (Gregor Kiczales). Ими же в 2001 году было
разработано аспектно-ориентированное расширение для
языка Java, получившее название AspectJ.
3. Система как набор функциональных
требований
Требования к банковской системе
Функциональные требования: Общесистемные требования:
– работа со счетами – авторизованный доступ
– валютные операции – целостность транзакций
– работа с кредитными картами – ведение журнала событий
– работа с банкоматами – мониторинг производительности
– ... – обработка исключительных
ситуаций
– валидация данных
– многопоточность
– ...
– ...
4. Проблема сквозной функциональности
public class SomeBusinessClass {
// Данные, отвечающие за состояние объекта
// Вспомогательные данные, отвечающие за:
// - авторизованный доступ к данным;
// - целостность транзакций;
// - ведение журнала событий;
// - безопасность междупоточного взаимодействия;
// - ...
public void someOperation(Object...params) {
// проверить уровень доступа к данным
// запретить доступ к данным другим потокам выполнения
// занести в журнал отметку о начале операции
// Реализация логики данного метода
// занести в журнал отметку о конце операции
// разрешить доступ к данным другим потокам выполнения
}
}
5. Пространство требований и
реализации
Безопасность
Управление
транзакциями
Безопасность
Отображение
в реализацию
Бизнес-логика
ия е
кц ни
ми
Бизнес-логика
за ле
ан ав
тр Упр
Пространство требований Пространство реализации
Сворачивание многомерного пространства требований
в одномерное пространство реализации
7. Рассредоточенный код
Вызовы API
Модуль счетов
Модуль
безопасности
Модуль банкомата
Модуль БД
8. Влияние запутанного и
рассредоточенного кода на
проектирование и реализацию
– Плохое прослеживание назначения модуля
– Низкая пригодность кода для повторного
использования
– Большая вероятность ошибок
– Трудности в сопровождении
9. Выделение сквозной
функциональности с помощь аспектов
Автоматически
интегрированные
вызовы
Модуль счетов
Вызовы API
Аспект Модуль
безопасности безопасности
Модуль банкомата
Модуль БД
10. Фундаментальные понятия АОП
● JoinPoint — строго определённая точка выполнения программы, ассоциированная с контекстом
выполнения (вызов метода, конструктора, доступ к полю класса, обработчик исключения, и т.д.)
● Pointcut — набор (срез) точек JoinPoint удовлетворяющих заданному условию.
● Advice — набор инструкций, выполняемых до, после или вместо каждой из точек выполнения
(JoinPoint), входящих в заданный срез (Pointcut)
● Inter-type declaration* — способность аспекта изменять статическую структуру класса путем
добавления как новых полей и методов, так и иерархии класса.
● Aspect — основная единица модульности АОП, инкапсулирующая срезы точек выполнения
(Pointcut), наборы инструкци (Advice), а также Inter-type определения*.
● Weaving – процесс интеграции правил вплетения кода аспектов с кодом, ответственным за
бизнес-логику, результатом которого является конечная система.
* – доступно только в AspectJ
12. Joinpoints, доступные в AspectJ
Категория Преставление
Выполнение метода Тело метода
Вызов метода Вызов метода
Выполнение конструктора Тело конструктора
Вызов конструктора Вызов конструктора
Чтение поля класса Чтение поля
Запись в поле класса Запись поля
Обработка исключений catch-блок обработки исключения
Инициализация класса Блок статической инициализации
Инициализация объекта Инициализация в конструкторе
13. Отношения между Joinpoints,
шаблонами сигнатур и Pointcuts
Сигнатура типа
public class Account { Account
private double balance;
private int accountNumber; Pointcut
Сигнатура конструктора
public Account.new(int) public Account(int accountNumber) { within(Account)
this.accountNumber = accountNumber;
}
Pointcut Сигнатура метода
execution(Account.new(int)) public void credit(double amount) { public * Account.*(..)
balance += amount;
}
Pointcut Pointcut
public void debit(double amount)
set(private double Account.balance) throws InsufficientBalanceException { execution(public * Account.*(..))
if (balance < amount) {
throw new InsufficientBalanceException(
Сигнатура поля "Недостаточный баланс.");
} else {
private double Account.balance balance -= amount;
}
}
Pointcut
get(private double Account.balance) // ...
}
14. Pointcut. Мета-символы и логические
операторы
Символ Пример использования
* call(public *.new(int))
execution(public int *.get*())
call(public Account.new(..))
..
call(public int *.*(Account, .., double))
+ execution(public Account+.new(..))
Мета-символы
Операция Пример использования
&& call(* debit(..)) && target(Account+)
|| call(* int Account.*(..)) || call(* double Account.*(..))
! !whitin(Account)
Логические операторы
16. Конструкция Advice
Advice – набор инструкций сквозной функциональности, добавляемый до,
после или вместо JoinPoint, входящих в указанный Pointcut.
● Before – набор инструкций выполняемый перед выполнением инструкций
входящих в описываемую Joinpoint.
● after returning – набор инструкций выполняется после успешного
возвращения значения из описываемой точки выполнения.
● after throwing – набор инструкций выполняется после возникновения
исключительной ситуации в описываемой точке выполнения.
● after – набор инструкций выполняется после возвращения из
описываемой точки выполнения в любом случае.
● around – набор инструкций выполняется вместо описываемой точки
выполнения.
20. @AspectJ
@Aspect
public class PureJavaAspect {
@Pointcut(value = "execution(* Content.*(..))")
public void parents() {}
@Before("parents()")
public void before(JoinPoint joinPoint) {
Logger.log("Before " + joinPoint.toLongString());
}
@DeclareWarning("get(* System.*) && !within(cnc.logging.Logger)")
static final String warning = "Do not use System.out";
}
21. AspectJ. Средства разработки
Консольные:
– ajc - компилятор AspectJ
– ajdoc - средство документации AspectJ в стиле
javadoc
Визуальные:
– плагин для Eclipse
– плагин для NetBeans
– плагин для IntelliJ IDEA
22. Преимущества АОП
– Упрощение дизайна
– Более понятная реализация
– Уменьшение объёма исходного кода
– Уменьшение количества ошибок
– Уменьшение связанности между классами
– Улучшение повторного использования кода
– Уменьшение затрат на поддержку ПО
– Снижение стоимости разработки
23. Недостатки АОП
– Порог вхождения
– Похоже на магию
– Некоторые недостатки реализации
– Некоторые недостатки средств разработки
– Изучение существующих практик применения для
снижения рисков