Оглавление
Что
такое Аспектно Ориентированное программирование?
Примеры AOП
Аспектно-ориентированное
расширение для Xbase++
Класс
XppAspectEntry
Что
такое Аспектно Ориентированное программирование (AOП)?
В
нескольких словах, AOП это новая парадигма расширения
возможностей программирования, позволяющая выполнять
обрамляющий код во время вызова контролируемого
кода.
В нашей
реализации, обрамляющий код может быть блоком кода, функцией или специальным
объектом (на основе класса XppAspectEntry).
Контролируемым кодом может быть функция (процедура) или метод какого-либо
класса. Контроль над защищенными или скрытыми методами так же возможен
в полной мере.
Обрамляющий
код имеет полное управление над контролируемым кодом, он может изменить
любой параметр контролируемого кода или заменить возвращаемое значение
собственным. Обрамляющий код может быть вызван до, после,
и вместо контролируемого
кода.
Примеры
AOП
Самый
известный пример применения АОП это использование для вывода отладочной
информации.
Пример ниже
показывает как вывести на экран параметры и возвращаемое значение при
каждом вызове метода checkPayment класса Payment:
//Вывод параметров с использованием обрамляющей функции
//установим обрамляющую функцию (только для oPayment)
aspects():wrapMethod(oPayment,"checkPayment","logPayment")
...
Func logPayment(oAspect,lBefore)
If lBefore
?"object=",oAspect:getObject()
?" paymentPars=",oAspect:getParamA()
Else
?"paymentReturn=",oAspect:getReturn()
End
Return NIL
|
Другим примером
использования техник AOП может быть обработка и изменение параметров
контролируемого кода.
Код ниже
устанавливает обрамляющий код (в виде объекта) для метода XbpStatic:setCaption.
Объект MyCaptions изменяет заголовки в верхний регистр на лету.
//Обработка параметров с использованием обрамляющего объекта
//создадим обрамляющий объект
oAdvice:=MyCaptions():new()
//чтобы перехватывать вызовы всех объектов унаследованных
//от XbpStatic мы устанавливаем lFilter в .F.
aspects():wrapMethod(XbpStatic(),"setCaption",oAdvice,.F.)
...
//обрамляющий класс
//используется только метод beforeCall
Class MyCaptions From XppAspectEntry
Exported:
Inline Method beforeCall()
If ::pCount()>0
//изменим заголовок в верхний регистр
::setParam(1,Upper(::getParam(1)))
End
Return NIL
EndClass |
Аспектно-ориентированное
расширение для Xbase++
aspects():wrapMethod(object|objectsList,
methodName, functionName|codeblock|oAdvice, lFilter) -> oRetAdvice
устанавливает
обрамляющий код для контролируемого метода
Параметр |
Описание |
1. object|objectsList |
объект
или массив объектов, которые нужно контролировать
Если третий параметр oAdvice,
то object может быть NIL. |
2. methodName |
имя
контролируемого метода |
3. functionName
codeblock/codeblockA
oAdvice |
имя
обрамляющей функции. Эта функция получает два параметра, oAdvice и
lBefore. oAdvice это объект типа XppAspectEntry и
если управление передано перед вызовом контролируемого кодаt
method, то lBefore равно .T.,
иначе .F..
ВНИМАНИЕ: Обрамляющая
функция должна возвращать NIL.
обрамляющий блок кода, вызываемый перед контролируемым методом
или массив из двух блоков кода, первый для вызова перед, а второй
после контролируемого метода (значения могут быть NIL).
ВНИМАНИЕ: Обрамляющая блок должен возвращать NIL.
обрамляющий объект, наследованный от класса XppAspectEntry.
Метод ::beforeCall()
вызывается перед контролируемым методом и ::afterCall()
вызывается сразу после.
Полную информацию о XppAspectEntry смотри ниже. |
4. lFilter |
По
умолчанию (.T.),
обрамляющий код вызывается только для объектов, указанных в object|objectsList.
Для
контроля над всеми объектами такого же типа, как указанные
в object|objectsList,
передайте .F..
В этом случае, вызов oAdvice:getObject() позволяет
узнать текущий контролируемый объект.
|
aspects():wrapFunction(targetFunction, functionName|codeblock|oAdvice,
lFilter) -> oRetAdvice
Параметр |
Описание |
1. targetFunction |
имя
контролируемой функции. |
остальные параметры имеют такое же значение как и при вызове :wrapMethod()
|
Класс XppAspectEntry
Этот
класс используется для контроля над функцией или методом
Автоматически
вызываемые методы
::beforeCall()
Этот метод
вызывается перед контролируемым кодом
::afterCall()
Этот метод
вызывается после контролируемого кода
::checkValid(object)
Этот метод
вызывается автоматически когда требуется определить, входит
ли
object в список контролируемых объектов для данного
XppAspectEntry.
В этом методе вы можете определить собственный алгоритм фильтрации.
ВНИМАНИЕ: если
параметр lFilter при
вызове aspects():wrapMethod(..) был .F.,
то объекты не проверяются и метод ::checkValid()
не вызывается.
Управление
списком контролируемых объектов
::addObjects(object|objectsList)
Добавляет object|objectsList к
списку контролируемых объектов данным XppAspectEntry.
::clearObjects()
Отменяет
фильтрацию, без отмены контроля вообще. Будут контролироваться все
объекты такого же типа (класса) как указанные при вызове aspects():wrapMethod(..).
В этом случае, вызов ::getObject() позволяет
узнать текущий контролируемый объект.
Управление
над параметрами и возращаемым значением
::PCount() ->
numParams
Возвращает
количество параметров переданных контролируемому коду.
::getParamA() -> aParams
Возвращает
все параметры в виде массива.
::getParam(nParam) -> paramValue
Возвращает
указанный параметр контролируемого кода.
::setParam(nParam,value)
Изменяет
параметр на новое значение.
::getReturn() -> returnValue
Возвращает
текущее возвращаемое значение контролируемого кода.
::setReturn(returnValue)
Устанавливает
новое возвращаемое значение контролируемого кода.
::getObject()
Возвращает
текущий контролируемый объект.
Внимание: этот вызов допустим только для объектов XppAspectEntry
полученных вызовом aspects():wrapFunction(..).
Управление
контролируемым
кодом
::disableBody()
Запрещение
автоматического вызова контролируемого кода. Этот запрет нет отменят
контроль, ::beforeCall()
и ::afterCall() будут продолжать вызываться.
::enableBody()
Разрешение
автоматического вызова контролируемого кода между
::beforeCall()
и ::afterCall().
©2006
Eleus Software |