flash.utils.Proxy и Object.constructor

Небольшой совет для всех кто активно использует или собирается использовать класс flash.utils.Proxy – всегда реализуйте свойство constructor возвращающее тип(экземпляр типа Class) данного объекта.

Это свойство есть у всех объектов расширяющих Object класс, но природа наследников flash.utils.Proxy такова, что любой «получить значение свойства» запрос проходит через метод flash_proxy::getProperty(), кроме тех случаев, когда запрашивается свойство или поле описаное в наследнике flash.utils.Proxy. Поэтому если не описать это свойство вовремя – при запросе происходит вызов метода flash_proxy::getProperty(), а дальше приходит неизвестность, т.е. вы теряете очень важную и полезную особенность присущую обычным объектам т.к. наиболее быстрый и правильный способ узнать тип объекта, это обратиться к свойству constructor любого объекта.

Я обычно описываю это свойство двумя способами:

Для абстрактного класса:

public class AbstractWrapper extends Proxy{public function get constructor():Class{
		return getDefinitionByName(getQualifiedClassName(this)) as Class;
	}

В таком случае не будет ошибки, если в дочернем классе забыть переписать этот метод. ;)

А для конкретного класса:

;public class Wrapper extends Proxy{public function get constructor():Class{
		return Wrapper;
	}

Можно, конечно и так:

public class Wrapper extends Proxy{public const constructor:Class = Wrapper;
	}

Но, чревато последствиями, если класс не обозначить как final – при наследовании нет возможности изменить значение константы.

Метки: , , , ,

Комментарии (2) на «flash.utils.Proxy и Object.constructor»

  1. yzh44yzh:

    Так а что произойдет, если этого не делать?
    Я вот не делаю. Но у меня такой объект в единственном экземпляре, синглетон.

  2. Ну, для синглтона вряд ли опасно, а вот для объектов «в обороте» может быть, если вы их кастуете, к примеру. Скажем, поступают в метод разные объекты, он их сортирует через
    switch(Object(target).constructor){
    case Wrapper:
    this.doSomethingWithWrapper(target as Wrapper);
    break;
    case WrapperInternal:
    this.doSomethingWithWrapperInternal(target as WrapperInternal);
    break;
    case AnotherTarget:
    this.doSomethingWithAnotherTarget(target as AnotherTarget);
    break;
    В таком случае при получении значения свойства «constructor», если если оно не было описано, может вернуться значение этого свойства только взятое у внутреннего объекта, которое обёрнуто в проксю и кастинг приведёт к NULL. Пример, конечно, очень условный и в таком случае надо либо юзать пару getDefinitionByName & getQualifiedClassName и не парить себе мозги; либо юзать Object.constructor но позаботиться о правильном значении этого свойства. Я предпочёл второй вариант и всем рекомендую.
    Интересно, а зачем понадобилась прокся как синглтон и почему не использовали композицию с состояниями/адаптер?

Добавить комментарий

Вы должны авторизоваться для отправки комментария.