代码改变世界

【原】Flash AS3反射机制简述

2010-05-22 09:48  bugfly  阅读(1357)  评论(0编辑  收藏  举报

 

    记得第一次尝试通过网络找AS3的反射机制用法的时候,我搜遍了百度和谷歌的相关信息,基本上没有一篇满意的文章可以很好地描述用法,为了让有着同一目的你,我简述一下我在两个AS3项目用到的反射机制的作用和用法,高手们就见笑了。

1.为什么要用反射机制去生成对象?

     这个问题如果你没一定的面向对象基础可能比较难理解以下内容。首先,其目的是为了解耦,解除代码间的耦合程度,降低维护成本。如果你用过工厂模式,或者对维护噩梦有所感悟就会知道为什么要解耦了。无论什么工厂模式,即使是抽象工厂模式也好,也不能根本性解除代码中生成对象的耦合问题,只能说能大大降低耦合程度,因为你生成对象必然要new此对象,而这意味着没可能在不修改代码的前提下扩展新的内容,例如你要增加一些新的子类,必然要在生成的地方new一个此类对象。恩,实质就是修改已有代码去扩展新功能,违反了开闭原则,即使影响很小很小,但确实是违反了。小程序,小项目确实没有体现什么弊端,而当你程序达到足够庞大的时候,你就会发现,修改代码是一件很痛苦的事。正是这个原因,反射机制出现了。反射机制的原理我的理解是,通过一个中间件去配置要生成的对象,一般是通过XML文件实现,把你新增加的类的名字记录在XML配置文件内,通过已有的程序代码反射这个从配置文件里读取出来的类名字,动态生成对应类的对象。或许你还是有点不明白。我们直接看代码。注:我打出的代码基本上是即时手打的,没有经过编译测试,但问题影响不大,真有兴趣要深入了解的,可以HI我,或者留言给我,我这里有几份相关小测试程序的源代码。

 

(1)外部的XML配置文件内容

<displayObject basePackage="com.example">
<object name="m_textField" className="StartState" textContent="success!" x="100" y="200"/>
</displayObject>

 

 

(2)接口(IState)

package com.example{

public interface IState{

function setText(n_text:String);
}
}

 

(3)子类(StartState)

StartState
package com.example{

public class StartState implements IState{

private m_text:String;

public function StartState(){}

public function setText(n_text:String)

{

this.m_text=n_text;

}
}
}

 

(4)调用类,由于为了简洁展现内容我直接把读写XML的逻辑写在了文档类,也就是所谓的调用类,方便大家阅读。:)

 

文档类
package{
import com.example.*;
import flash.display.*;
import flash.events.*;
import flash.utils.*;
import flash.net.*;

public class DocClass extends MovieClip{

private var m_xmlData:XML;
private var m_urlRequest:URLRequest;
private var m_urlLoader:URLLoader;

public function DocClass(){

this.m_urlRequest=new URLRequest("xml/test.xml");
this.m_urlLoader=new URLLoader(m_urlRequest);
this.m_urlLoader.addEventListener(Event.COMPLETE,xmlDataComplete);
}

public function xmlDataComplete(e:Event){

this.m_xmlData=XML(m_urlLoader.data);
readXmlData();
}

public function readXmlData()
{
var n_xmlList:XMLList
=this.m_xmlData.*;

for each(var n_xmlObject:XML in n_xmlList)
{
var TempClass:Class
=getDefinitionByName(m_xmlData.@basePackage+"."+n_xmlObject.@className)as Class;
var n_textClass:IState
=new TempClass();
n_textClass.x
=Number(n_xmlObject.@x);
n_textClass.y
=Number(n_xmlObject.@y);
n_textClass.setText(n_xmlObject.@textContent);
}
}
}
}

 

以上代码就是大致的使用流程,代码不重要,重要的是理解这个使用思路,每当你添加了一种子类,不用修改源文件的代码,只需要修改配置文件,对应的类名,就可以实现扩展,当然由于FLASH的特殊编译环境,你必须要让FLASH编译器知道这个子类的存在,如常有的做法是定义一个相关类的变量名,不过我不赞成这种方式,更好的方式你,让对应的元件绑定这个类的名字,也就是链接起来。

 

好了,本人愚见,高手见笑了。希望对你有帮助!