用于延迟实例化的Flex强类型代理类

时间:2011-11-22 00:40:22

标签: actionscript-3 flex code-generation proxy-classes graniteds

有没有人知道一个框架,最好让Flex编译器运行一个扩展,或者只是一个构建步骤,我们可以生成应用程序数据模型的强类型代理类。

我们想对代理服务器做两件事:

  1. 在运行时,我们想要懒惰地解析并实例化访问的实例(类似于Java的Hibernate如何具有Lazy代理对象)
  2. 在编辑器应用程序中,我们希望实现setter调用,以便我们可以跟踪哪些对象已被修改
    • 代理在这种情况下非常必要,除了以编程方式设置ChangeWatcther之外,因为我们需要跟踪数组添加/删除并可能跟踪“引用”对象,以便在更改“引用键”时我们知道保存这些对象用键引用它
  3. 在第一种情况下,我们希望代理在从序列化数据加载该对象时基本上是抽象的,但如果它是真实对象,仍然使用相同的公共属性和数据访问模式传递它的引用。

    基本上,代理会在第一次调用方法时实例化对象。

    我知道我们可以使用一些AS3字节码库,如as3-commons-bytecode

    或者可能重新利用GraniteDS代码生成。

    我更喜欢生成代码,因为它是一个确定性的东西,如果我们能够在运行时更容易调试它,那就太好了。

    当MXMLC从MXML文件生成AS3代码时,是否有人知道我是否可以执行类似MXMLC的操作。

    无论如何在编译管道中控制“何时”我可以生成代码,因为我们有很多数据对象使用公共字段而不是getter / setter,但那是[Bindable]所以如果我可以生成代理基于生成的getter / setter方法。

    这是一个示例应用程序数据对象和代理类:

    [Bindable]
    public class PersonDTO implements Serializable {
        private var _name:String;
    
        private var _age:Number
    
    
        public function get age():Number {
            return _age;
        }
    
        public function set age(a:Number):void {
            _age = a;
        }
    
        public function get name():String {
            return _name;
        }
    
        public function set name(n:String):void {
            _name = n;
        }
    
        public void readObject(data:*) {
            //...
        }
    
    }
    
    // GENERATED CLASS BASED ON PersonDTO
    public class LazyProxy_PersonDTO extends PersonDTO {
    
        private var _instance:PersonDTO = null;
        private var _instanceData:*;
    
        private function getInstance():void {
            if (_instance == null) {
                _instance = new PersonDTO();
                _instance.readObject(_instanceData);
            }
        }
    
        override public function get age():Number {
            //Ensure object is instantiated
            return getInstance().age;
        }
    
        override public function get name():String {
            //Ensure object is instantiated
            return getInstance().name;
        }
    
    }
    
    // GENERATED CLASS BASED ON PersonDTO
    public class LogChangeProxy_PersonDTO extends PersonDTO {
    
        //This will be set in the application
        public var instance:PersonDTO;
    
        //set by application
        public var dirtyWatcher:DirtyWatcherManager;
    
        override public function set age(a:Number):void {
            dirtyWatcher.markAsDirty(instance);
            instance.age = a;
        }
    
    }
    

1 个答案:

答案 0 :(得分:2)

深入研究AS3-Commons字节代码库,看起来它们支持生成代理类和拦截器。

  • http://www.as3commons.org/as3-commons-bytecode/proxy.html

    public class DirtyUpdateInterceptor implements IInterceptor {
    
    public function DirtyUpdateInterceptor() {
        super();
    }
    
    public function intercept(invocation:IMethodInvocation):void {
        if (invocation.kind === MethodInvocationKind.SETTER) {
            if (invocation.arguments[0] != invocation.instance[invocation.targetMember]) {
                invocation.instance.isDirty = true;
            }
        }
    }
    }