АОП в ActionScript 3 действительно сложно. Все проблемы имеют свои проблемы:
- проксирование: фактически работает нормально и прозрачно для программиста, но не для среды выполнения. Если какая-либо сигнатура функции ожидает объект типа A, то прокси для объекта типа A не сможет пройти проверку типов
- генерация байт-кода: ну, вроде работает, но не слишком хорошо. загрузка байт-кода в AVM2 происходит асинхронно, поэтому вы не можете сделать это вовремя. Кроме того, после загрузки байт-кода его невозможно удалить, поэтому вы не можете изменить класс во второй раз.
- все остальное многословно
Что вы можете сделать, это использовать Haxe . Haxe не только обладает другими преимуществами по сравнению с AS3, но также позволяет использовать некоторые AOP. Есть два подхода:
Динамические методы
В Haxe вы можете объявить методы динамическими. Они могут быть заменены во время выполнения, чтобы предоставить советы. Позвольте мне объяснить, что происходит под капотом. Следующий код Haxe:
public function foo(param1:Type1):Type2 { /*body*/ }
public dynamic function bar(param1:Type1):Type2 { /*body*/ }
Является эквивалентом следующего кода AS3:
public function foo(param1:Type1):Type2 { /*body*/ }
public var bar:Function = function (param1:Type1):Type2 { /*body*/ }
Использование последнего всегда работает хуже, чем первое, так как при этом требуется много проверок типов во время выполнения. Однако в Haxe вы не потеряете преимущества строгой типизации во время компиляции, в отличие от AS3.
Аналогично, используя аксессоры Haxe (которые действительно сильно отличаются от AS3), вы также можете использовать AOP для свойств:
public var foo(get_foo, set_foo):Type;
dynamic function get_foo() {//Haxe will automatically infer types: http://haxe.org/ref/type_infer
return this.foo;
}
dynamic function set_foo(param) {
return this.foo = param;
}
Любые динамические методы можно заменить во время выполнения, чтобы делать все, что вы пожелаете. AS2 позволил это, и библиотеки как as2lib предоставили AOP. к сожалению, он больше не доступен. Но я полагаю, что вы можете сами со всем разобраться.
проксирование
Haxe имеет понятие анонимных типов . Во время выполнения это просто *
(таким образом, следует ожидать потери производительности), но во время компиляции они безопасны для типа. Что вы можете сделать, это создать прокси для объекта любого типа, который вам нужен, и использовать его как контейнер AOP. Во всем вашем коде вы никогда не используете его тип явно, а скорее эквивалентный анонимный тип. Проблема с прокси, которую я описал, исчезнет. Единственное, что вам нужно сделать, это сделать небезопасное приведение вашего прокси к этому анонимному типу.