1.为什么要用反射机制去生成对象?
这个问题如果你没一定的面向对象基础可能比较难理解以下内容。首先,其目的是为了解耦,解除代码间的耦合程度,降低维护成本。如果你用过工厂模式,或者对维护噩梦有所感悟就会知道为什么要解耦了。无论什么工厂模式,即使是抽象工厂模式也好,也不能根本性解除代码中生成对象的耦合问题,只能说能大大降低耦合程度,因为你生成对象必然要new此对象,而这意味着没可能在不修改代码的前提下扩展新的内容,例如你要增加一些新的子类,必然要在生成的地方new一个此类对象。恩,实质就是修改已有代码去扩展新功能,违反了开闭原则,即使影响很小很小,但确实是违反了。小程序,小项目确实没有体现什么弊端,而当你程序达到足够庞大的时候,你就会发现,修改代码是一件很痛苦的事。正是这个原因,反射机制出现了。反射机制的原理我的理解是,通过一个中间件去配置要生成的对象,一般是通过XML文件实现,把你新增加的类的名字记录在XML配置文件内,通过已有的程序代码反射这个从配置文件里读取出来的类名字,动态生成对应类的对象。或许你还是有点不明白。我们直接看代码。注:我打出的代码基本上是即时手打的,没有经过编译测试,但问题影响不大,真有兴趣要深入了解的,可以HI我,或者留言给我,我这里有几份相关小测试程序的源代码。
(1)外部的XML配置文件内容
2 < object name ="m_textField" className ="StartState" textContent ="success!" x ="100" y ="200" />
3 </ displayObject >
这个是用来存放反射类信息的文件。
(2)接口(IState)
package com.example { public interface IState { function setText(n_text:String); }
}
(3)子类(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编译器知道这个子类的存在,如常有的做法是定义一个相关类的变量名,不过我不赞成这种方式,更好的方式你,让对应的元件绑定这个类的名字,也就是链接起来。