AS3与设计模式(策略模式)
- 格式:doc
- 大小:214.00 KB
- 文档页数:5
设计模式:常用设计模式及其应用设计模式是在软件设计中常见问题的解决方案的一种反复使用的经验总结。
它们是已经被证明有效的经典解决方案,可以帮助我们在开发过程中避免重复设计。
本文将介绍一些常用的设计模式及其应用。
1.单例模式单例模式是一个创建型的设计模式,它会确保一个类只有一个实例。
这在需要共享资源或控制唯一资源访问的场景下非常实用,例如线程池、日志记录器等。
2.工厂模式工厂模式是一种用于创建对象的创建型设计模式。
它定义了一个接口来创建对象,但将创建实例的过程延迟到子类中。
这样可以避免在代码中直接使用new操作符,增加了代码的灵活性和可维护性。
3.观察者模式观察者模式是一种行为型的设计模式,它定义了一对多的依赖关系。
当一个对象的状态发生变化时,它会自动通知它的依赖对象。
观察者模式常用于事件处理、GUI编程等场景。
4.装饰器模式装饰器模式是一种结构型的设计模式,它允许你通过将对象包装在一个装饰器对象中来动态地添加新的功能。
装饰器模式可以避免使用子类化的复杂性,提供了比继承更加灵活的方式来扩展功能。
5.策略模式策略模式是一种行为型的设计模式,它定义了一系列算法,并将每个算法封装在可以相互替换的策略对象中。
这使得算法可以独立于客户端的使用,提高了代码的灵活性。
6.适配器模式适配器模式是一种结构型的设计模式,它允许不兼容的接口之间进行适配。
适配器模式可以通过创建一个适配器类来实现两个不兼容接口之间的交互。
7. MVC模式MVC(Model-View-Controller)是一种架构模式,它将应用程序分为三个主要部分:模型、视图和控制器。
模型表示应用程序的数据和逻辑,视图负责显示数据,控制器接收用户输入并对模型和视图进行协调。
8.组合模式组合模式是一种结构型的设计模式,它将对象组合成树状结构以表示“整体/部分”层次结构。
组合模式使得用户对单个对象和组合对象的使用具有一致性,可以用来处理树形结构的问题。
9.迭代器模式迭代器模式是一种行为型的设计模式,它提供一种访问容器中各个元素的方法,而不需要暴露容器的内部结构。
软件开发中的设计模式有哪些在软件开发的领域中,设计模式就像是一套经过实践检验的解决方案,帮助开发者更高效、更优雅地解决常见的问题。
它们是软件开发中的宝贵经验总结,为构建可维护、可扩展和灵活的软件系统提供了有力的支持。
接下来,让我们一起探索一下软件开发中常见的设计模式。
一、创建型设计模式1、单例模式(Singleton Pattern)单例模式确保一个类只有一个实例存在,并提供一个全局访问点来获取该实例。
这在某些情况下非常有用,比如一个系统中只需要一个数据库连接池或者一个日志记录器。
想象一下,如果多个线程同时创建多个数据库连接池实例,不仅会浪费资源,还可能导致混乱。
通过单例模式,我们可以保证只有一个实例存在,有效地管理资源。
2、工厂模式(Factory Pattern)当我们需要创建对象,但又不想让客户端直接与具体的类进行交互时,工厂模式就派上用场了。
它定义了一个用于创建对象的接口,让子类决定实例化哪一个类。
比如,在一个汽车生产厂中,有不同类型的汽车(轿车、SUV 等),我们可以通过一个工厂类根据需求来创建相应类型的汽车对象,而客户端只需要向工厂请求即可,无需关心具体的创建细节。
3、抽象工厂模式(Abstract Factory Pattern)抽象工厂模式提供了一个创建一系列相关或相互依赖对象的接口,而无需指定它们具体的类。
例如,一个家具厂可能生产多种风格的家具(现代风格、古典风格),每种风格都有配套的椅子、桌子和沙发。
通过抽象工厂模式,我们可以根据用户选择的风格创建一整套家具,保证了风格的一致性和协调性。
4、建造者模式(Builder Pattern)建造者模式将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
比如构建一个电脑配置,我们可以有不同的 CPU、内存、硬盘等组件选择,通过建造者模式,可以清晰地定义构建的步骤和顺序,同时能够灵活地组合不同的组件来创建出各种不同配置的电脑。
第1篇一、实验背景随着软件工程的不断发展,设计模式作为一种解决软件开发中常见问题的有效方法,越来越受到广泛关注。
本次实验旨在通过学习设计模式,提高编程能力,掌握解决实际问题的方法,并加深对设计模式的理解。
二、实验目的1. 理解设计模式的基本概念和分类;2. 掌握常见设计模式的原理和应用;3. 提高编程能力,学会运用设计模式解决实际问题;4. 培养团队协作精神,提高项目开发效率。
三、实验内容本次实验主要涉及以下设计模式:1. 创建型模式:单例模式、工厂模式、抽象工厂模式、建造者模式;2. 结构型模式:适配器模式、装饰者模式、桥接模式、组合模式、外观模式;3. 行为型模式:策略模式、模板方法模式、观察者模式、责任链模式、命令模式。
四、实验过程1. 阅读相关资料,了解设计模式的基本概念和分类;2. 分析每种设计模式的原理和应用场景;3. 编写代码实现常见设计模式,并进行分析比较;4. 将设计模式应用于实际项目中,解决实际问题;5. 总结实验经验,撰写实验报告。
五、实验结果与分析1. 创建型模式(1)单例模式:通过控制对象的实例化,确保一个类只有一个实例,并提供一个访问它的全局访问点。
实验中,我们实现了单例模式,成功避免了资源浪费和同步问题。
(2)工厂模式:定义一个用于创建对象的接口,让子类决定实例化哪一个类。
实验中,我们使用工厂模式创建不同类型的交通工具,提高了代码的可扩展性和可维护性。
(3)抽象工厂模式:提供一个接口,用于创建相关或依赖对象的家族,而不需要指定具体类。
实验中,我们使用抽象工厂模式创建不同类型的计算机,实现了代码的复用和扩展。
(4)建造者模式:将一个复杂对象的构建与它的表示分离,使得同样的构建过程可以创建不同的表示。
实验中,我们使用建造者模式构建不同配置的房屋,提高了代码的可读性和可维护性。
2. 结构型模式(1)适配器模式:将一个类的接口转换成客户期望的另一个接口,使原本接口不兼容的类可以一起工作。
第一章 AS3的一些优化计算方法用乘法来代替除法(当除数可转化为有限数的时候)。
比如var n:Number = value * 0.5;要比var n:Number = value / 2;快。
但差别并不是很大。
只有在需要大量计算情况下,比如3D引擎中差别才比较明显。
用位运算代替除2或乘2。
比如10>>1要比10*2快,而10<<1要比10*2快。
从测试来看位运算几乎比乘除快一倍,但是一般情况下,我们不能选择位运算,比如我们就不能用13>>1来代替13/2,尽管前者比后者运算速度更快,但2者的运算结果却不一样。
所以还是要看具体情况。
用unit(或int(代替取整运算Math.floor(和Math.ceil(。
比如var test:uint = uint(1.5;要比var test:Number = Math.floor(1.5;快;而var test:uint = uint(1.5+1;要比var test:Number = Math.ceil(1.5;也快。
如果是Math.floor(,还可以用位运算(>>0来代替。
比如var test:uint =1.5>>0,比unit(或int(更快。
用乘-1来代替Math.abs(方法。
比如var nn:Number = -23;var test:Number= nn < 0 ? nn * -1 : nn;要比var nn:Number = -23;var test:Number = Math.abs(nn;快。
当然还有更多的优化计算的方法。
一般来说,低级运算要比高级运算速度;内部方法比调用其他方法速度快。
另外要注意的是,这些方法有的时候可能并一定适用。
第二章 Actionscript 优化指南原著 Marco Lapi,alias Lapo, aw译在这篇文章中,我们将讨论多种优化 Actionscript 代码的方法.此外我们也针对一些典型的游戏代码进行了系列测试,来最大限度的发掘、提高Flash播放器的性能。
Flash AS3单例模式通用类写法-Flash单例模式的优点:1.一个静态实例,把共享的属性方法能在任何一个程序集调用,信息有效的实现操作。
(数据以一个静态实例的模式贯通全局)2.有效降低大模块之间的耦合度。
(注意:缺点就是耗费内存资源。
单例不能滥用)(注意:单例模式,顾名思义。
只有一个实例的设计模式。
)单利模式的由来:我们只要仔细地想想看,全局变量确实可以提供一个全局访问点,但是它不能防止别人实例化多个对象。
通过外部程序来控制的对象的产生的个数,势必会系统的增加管理成本,增大模块之间的耦合度。
所以,最好的解决办法就是让类自己负责保存它的唯一实例,并且让这个类保证不会产生第二个实例,同时提供一个让外部对象访问该实例的方法。
自己的事情自己办,而不是由别人代办,这非常符合面向对象的封装原则。
通用类写法:(提供三种常用的)1.类只有一个实例package2 {3 public class Single4 {5 private static var instance:Single = new Single();67 private var _name:String = '';89 public function get name():String10 {11 return _name;12 }1314 public function set name(value:String):void15 {16 _name = value;17 }1819 public function Single()20 {21 if(instance)22 {23 throw new Error("Single.getInstance()获取实例");24 }25 }2627 public static function getInstance():Single28 {29 return instance;30 }31 }32 }2.类可以有多个实例,内部实例能贯通全局package2 {3 public class Single4 {5 private static var instance:Single;67 private var _name:String = '';89 public function get name():String10 {11 return _name;12 }1314 public function set name(value:String):void15 {16 _name = value;17 }1819 public function Single()20 {2122 }2324 public static function getInstance():Single25 {26 if(instance == null)27 {28 instance = new Single();29 }30 return instance;31 }32 }33 }3.只有一个实例,用内部类实现只能实例化一次,外部不能访问该内部类自然就实例化不了' package2 {3 public class Single4 {5 private static var instance:Single;67 private var _name:String = '';89 public function get name():String10 {11 return _name;12 }1314 public function set name(value:String):void15 {16 _name = value;17 }1819 public function Single(content:ConSingle)20 {2122 }2324 public static function getInstance():Single25 {26 if(instance == null)27 {28 instance = new Single(new ConSingle);29 }30 return instance;31 }32 }33 }3435 class ConSingle36 {3738 }在使用单利模式的时候,请注意一点。
细谈AS3程序性能优化程序性能优化是很多程序的心头病,也是很多新手望而却步的高深领域,笔者根据自己多年的开发经验以及同行前辈的指导,现总结以下优化方面:1.合理创建对象,减少对象的数目以降低gc使用完的对象,flash player的垃圾回器会回收他们的内存来重新使用。
不幸的是,这个过程是非常缓慢的而且我们不能控制它什么时候执行。
所以,尽量重用已经存在的对象而减少使用new来声明新的对象。
对这方面有帮助的一个技术是free lists。
2.对逻辑算法进行优化,减少多余的计算无论对于那一种程序,好的算法总是非常重要的,而且能够极大地提高程序性能,所以任何性能的优化第一步就是从算法或者说程序逻辑的优化开始,检查自己的程序是否有多余的运算,是否在没有必要的时候做了无用功,往往从这些方面就能找到那些导致性能低下的地方。
3.使用flash的源生代码代替as3一般情况下,使用flash player的原生代码做一些大负荷的工作要比使用as3去做好的多。
因为和调用flash player api(flash包里面的所有东西)里面的方法相比,在vm(虚拟机)里运行你自己的as3代码势必会带来一些间接成本。
不适用这个规则的例外是,api有时会做你不想做的事情,比如分配内存4.减少内存分配以降低gc除了你预料到的内存分配,比如通过使用某个新的操作触发某个事件,还有很多隐藏的分配,比如关联的字符串对象、flash player自己创建的对象,如事件。
这些分配很慢,使用完了回收他们更慢,所以试着去掉这样的分配。
5.不要使用任何动态的东西这包括动态的函数(如无特征的函数和被声明为局部变量的函数),如Object和MovieClip这样的对象,用”[]“操作符访问字段、无类型的变量。
这些都比使用相应的静态量(如正规的函数、非动态类、”.”运算符、有类型的变量)要慢的多。
6.把更多的事情交给gpu现在在flash里面(fp11)我们除了可以使用cpu外,还可以使用显卡的gpu。
设计模式中的多态——策略模式详解⽬录策略模式和java语⾔的多态特性有些像。
java的多态特性允许我们⾯向接⼝编程,不⽤关⼼接⼝的具体实现。
接⼝所指向的实现类,以及通过接⼝调⽤的⽅法的具体⾏为可以到运⾏时才绑定。
这么做最⼤的好处是在尽可能实现代码复⽤的前提下更好地应对具体实现类的变化。
⽐如我想增加⼀种接⼝的实现或者修改原有实现类的某个⾏为,那我⼏乎不⽤修改任何客户端代码。
策略模式可以说正是这种思想在设计模式上的运⽤。
它可以使我们更好的复⽤代码,同时使程序结构设计更有弹性,更好的应对变化。
2. 策略模式详解2.1 策略模式定义策略模式定义了⼀系列算法,并将每⼀个算法封装起来,⽽且使它们还可以相互替换。
策略模式让算法独⽴于使⽤它的客户端⽽独⽴的变化。
可以使⽤多态进⾏类⽐来理解策略模式的定义。
⼀系列算法可以理解成接⼝的不同实现类,因为不同实现类都实现了相同的接⼝,因⽽它们也可以相互替换。
策略模式让算法独⽴于客户端⽽变化与接⼝的实现类可以独⽴于使⽤接⼝的客户端变化类似。
2.2 策略模式的UML类图从UML类图上可以看出,策略模式中主要有3个⾓⾊抽象策略接⼝上图中的Strategy即抽象策略接⼝,接⼝中定义了抽象的策略算法algorithm()。
具体的策略实现类上图中的StrategyA和StrategyB即具体的策略实现。
不同的策略实现类都实现了抽象策略接⼝,并重写了其抽象策略⽅法。
因为都实现了相同的策略接⼝,因⽽算法可以相互替换,并且可以动态的改变具体的算法实现。
封装策略的上下⽂环境上图中的Context即策略的上下⽂环境。
它屏蔽了⾼层模块对策略算法的直接访问,封装了可能存在的变化。
⽽且提供了修改Strategy的setter⽅法,可以动态的改变算法的具体实现。
3.策略模式的优点我们可以结合使⽤策略模式的例⼦并与其它实现⽅案进⾏对⽐来看看策略模式到底有什么好处3.1 ⼀个使⽤策略模式的例⼦定义⼀个汽车类Car。
1.getDefinition - 模块化你的程序为了加快程序的加载..我们通常会把不同的功能模块做成不同的swf,要需要的时候再实行加载.开始的时候..我们通常会直接使用loader加载,,然后用addChild把loader显示出来..这样就完成了最简单的"模块"化了..当然进一步..我们会发现上面的方法已经满足不了我们的需求..有时候我们需要的不是一个实例对象,我们想得到的是一个类..让我们能够像调用自身库中的类一样能够实例化..复制..等等这时候我们就能够使用ApplicationDomain(应用程序域),把加载进来的swf中的库的东西当自己的库一样使用概念性的东西还是不好说...直接看代码吧..下面的代码就是一个最简单的例子//还是需要loader先实行加载var loader:Loader = new Loader()loader.contentLoaderInfo.addEventListener(PLETE, loaderComplete)//sub.swf是一个外部swf,该swf库里有一个链接名叫"k_abc"元件loader.load(new URLRequest("sub.swf"))function loaderComplete(e:Event):void{//创建一个应用程序域var app:ApplicationDomain = loader.contentLoaderInfo.applicationDomain//使用getDefinition返回sub.swf的库中链接名为k_abc的Classvar c:Class = app.getDefinition("k_abc") as Class//接下来就不多说了..像普通的类一样操作就2.AS3中for循环创建(复制)对象在as2中,我们经常使用for来创建或复制多个相同的对象,到了as3,因为建立对象的方法的改变,以前的方法已经不适用了.今天介绍一下as3的方法:方法常用的有两种,第一种适用所有的对象,方法是先建一个数组,然后把建立的对象的引用指定对数组相对应的索引第二种适用显示对象,其实在as3中,都应该用这种方式,就是给对象指定name,然后使用getChildByName的方式来引用该对象.//通用的方法,适用所有对象var obj:Array = new Array()for(var i:uint=0;i<10;i++){var m:MovieClip = new MovieClip()addChild(m)obj["mc"+i] = m}trace(obj["mc1"])//适用显示对象for(var k:uint=0;k<10;k++){var mm:MovieClip = new MovieClip() = "mc"+kaddChild(mm)}trace(getChildByName("mc1"))//通用的方法,适用所以对象var obj:Array = new Array()for(var i:uint=0;i<10;i++){var m:MovieClip = new MovieClip() addChild(m)obj["mc"+i] = m}trace(obj["mc1"])//适用显示对象for(var k:uint=0;k<10;k++){var mm:MovieClip = new MovieClip() = "mc"+kaddChild(mm)}trace(getChildByName("mc1"))另外,有时候我们会遇到这样的情况var obj0:MC0 = new MC0()var obj1:MC1 = new MC1()var obj2:MC2 = new MC2()var obj3:MC3 = new MC3()这个时修,我们能够使用getDefinitionByName,用字符串返回类for(var i:uint=0;i<4;i++){var _class:Class = getDefinitionByName("MC"+i) as Classvar m = new _class()addChild(m)}3.代理类对于代理类,它的作用就是在不能传参数的时候帮助你传参数,什么时候不能传参数,像:addEventListener(PLETE,function)这个时候如果我们需要给function参指定的参数以达到不同的效果,就需要用到代理..,我们看看以下的用了代理函数的代码addEventListener(PLETE,getFun(function,args))这样,我们就可以在本来不可以传参的情况下传送参数.其中getFun就是代理函数.(一般网上都已经直接写成了代理类),getFun会帮我们把function,args生成一个无参数的函数再传给addEventListener,那么我们原来的function只需要写成function(e:Event[,参数]):void{//代码}就可以了function getFun(_function:Function,...alt):Function{ var _fun:Function = function (e:*):void {var _alt:Array = new Array()_function.apply(null,_alt.concat(e,alt));};return _fun;}4.让对象removeChild时自动删除子对象/属性/侦听在AS3里..我们无法手动完全删除一个对象,,以MovieClip为例..我们只有在删除它的时候除了removeChild(对象)外还必须清空它的子对象删除所有动态添加的属性删除所有侦听删除所有引用然后等待垃圾回收,可是实际操作的时候..在长长的代码当中..经常会忘记自己什么时候写了侦听..什么时候添加了动态属性其实,,我们可以借用显示对象中的Event.REMOVED,在删除对象的时候,让对象自己调用删除函数,删除相关的东西下面这个类继承了MovieClip,当他的实例在removeChild的时候,对象将"自我毁灭"package net.L4cd.display{import flash.display.MovieClip;import flash.events.Event;dynamic public class iMovieClip extends MovieClip{private var lis:Array;//定义一数组保存侦听public function iMovieClip(){lis = new Array()addEventListener(Event.REMOVED,remove)//侦听删除事件}//重写addEventListener,在增加侦听的时候..把相应的事件保存到数组override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{lis.push([type,listener,useCapture])super.addEventListener(type,listener,useCapture,priority ,useWeakReference)}//"自我毁灭"的方法private function remove(e:Event):void{if(e.currentTarget != e.target)returnstop()//删除子对象trace("删除前有子对象",numChildren)while(numChildren > 0){removeChildAt(0)}trace("删除后有子对象",numChildren)//删除动态属性for(var k:String in this){trace("删除属性",k)delete this[k]}//删除侦听for(var i:uint=0;i<lis.length;i++){trace("删除Listener",lis[i][0])removeEventListener(lis[i][0],lis[i][1],lis[i][2])}lis = null}}}package net.L4cd.display{import flash.display.MovieClip;import flash.events.Event;dynamic public class iMovieClip extends MovieClip{private var lis:Array;//定义一数组保存侦听public function iMovieClip(){lis = new Array()addEventListener(Event.REMOVED,remove)//侦听删除事件}//重写addEventListener,在增加侦听的时候..把相应的事件保存到数组override public function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int = 0, useWeakReference:Boolean = false):void{lis.push([type,listener,useCapture])super.addEventListener(type,listener,useCapture,priority,useWeakReference)}//"自我毁灭"的方法private function remove(e:Event):void{ if(e.currentTarget != e.target)return stop()//删除子对象trace("删除前有子对象",numChildren) while(numChildren > 0){ removeChildAt(0)}trace("删除后有子对象",numChildren)//删除动态属性for(var k:String in this){trace("删除属性",k)delete this[k]}//删除侦听for(var i:uint=0;i<lis.length;i++){trace("删除Listener",lis[i][0])removeEventListener(lis[i][0],lis[i][1],lis[i][2])}lis = null}}}然后我们另外新建一个flash,直接在时间轴上写下以下代码import net.L4cd.display.iMovieClip;var mc:MovieClip = new iMovieClip()mc.addEventListener(Event.ADDED,aaaa)mc.addEventListener(Event.ADDED_TO_STAGE,aaaa) mc.addEventListener(Event.ENTER_FRAME,aaaa)mc.addEventListener(MouseEvent.CLICK,aaaa)mc.addEventListener(MouseEvent.MOUSE_DOWN,aaaa) mc.a = ""mc.b = "我是动态属性2" = "我是MC"addChild(mc)function aaaa(e:Event){}removeChild(mc)mc = nullimport net.L4cd.display.iMovieClip;var mc:MovieClip = new iMovieClip()mc.addEventListener(Event.ADDED,aaaa)mc.addEventListener(Event.ADDED_TO_STAGE,aaaa) mc.addEventListener(Event.ENTER_FRAME,aaaa) mc.addEventListener(MouseEvent.CLICK,aaaa)mc.addEventListener(MouseEvent.MOUSE_DOWN,aaaa) mc.a = ""mc.b = "我是动态属性2" = "我是MC"addChild(mc)function aaaa(e:Event){}removeChild(mc)mc = null运行后.,,输出框就会出现删除前有子对象0删除后有子对象0删除属性 b删除属性 a删除Listener removed删除Listener added删除Listener addedToStage删除Listener enterFrame删除Listener click删除Listener mouseDown删除前有子对象0删除后有子对象0删除属性 b删除属性 a删除Listener removed删除Listener added删除Listener addedToStage删除Listener enterFrame删除Listener click删除Listener mouseDown这样,,,我们能做的事都已经做完了..等垃圾回收进行回收就ok了上面的remove方法就是mc在移除的时候,对自己进行的清理,,注意的是,以上只针对MovieClip进行的清理,每个类或你自定义的类都有不同..如Sprite不需用要stop(),不需要删除动态属性..等等..这个就由你自己去发挥~写一组自己的"自我毁灭"类..还有需要注意的是..像有时候,你只想removeChild,而不想进行删除,这样可以把上面的代码进行修改.把remove设置为公开的方法然后把addEventListener(Event.REMOVED,remove)去掉..最后在你想删除对象的时候,,,再调用remove()就ok了..5.自定义双击事件- iDoubleClickflash从as3开始支持双击事件..我们只需要使用对象.doubleClickEnabled = true,再侦听MouseEvent.DOUBLE_CLICK事件~就可以使用双击事件可是发现了一个不足的地方..如果我们同时侦听双击跟单击事件,,那当双击的时候.就会出现两个事件同时发生..这种情况实在不是很符合我们一般的需求..看来还是要用as2的老办法,用单击间的延时..来判断单击与双击..不过由于as3的事件机制~~我们完全可以模拟发现双击..直接看看应用代码//导入类import net.L4cd.*;//启用双击事件,注意一下.这里的200是指两次点击之前的延时.iDoubleClick.enable(mc,200)//另外可以使用iDoubleClick.disable(mc) 来取消自定义双击//像平常一样侦听mc.addEventListener(MouseEvent.DOUBLE_CLICK,mcDouCl ick)mc.addEventListener(MouseEvent.CLICK,mcClick) function mcClick(e:MouseEvent):void{trace(e)}function mcDouClick(e:MouseEvent):void{trace(e)}//导入类import net.L4cd.*;//启用双击事件,注意一下.这里的200是指两次点击之前的延时.iDoubleClick.enable(mc,200)//另外可以使用iDoubleClick.disable(mc) 来取消自定义双击//像平常一样侦听mc.addEventListener(MouseEvent.DOUBLE_CLICK,mcDouCl ick)mc.addEventListener(MouseEvent.CLICK,mcClick)function mcClick(e:MouseEvent):void{trace(e)}function mcDouClick(e:MouseEvent):void{trace(e)注意使用了自定义事件后就不要使用doubleClickEnabled = true,以免冲突然AS3 用for循环创建(复制)对象在as2中,我们经常使用for来创建或复制多个相同的对象,到了as3,由于建立对象的方法的改变,以前的方法已经不适用了. 今天介绍一下as3的方法:方法常用的有两种,第一种适用所有的对象,方法是先建一个数组,然后把建立的对象的引用指定对数组相应的索引第二种适用显示对象,其实在as3中,都应该用这种方式,就是给对象指定name,然后使用getChildByName的方式来引用该对象. ===========================================================================//通用的方法,适用所以对象var obj:Array = new Array()for(var i:uint=0;i<10;i++){var m:MovieClip = new MovieClip()addChild(m)obj["mc"+i] = m}trace(obj["mc1"])======================================================= ====================//适用显示对象for(var k:uint=0;k<10;k++){var mm:MovieClip = new MovieClip() = "mc"+kaddChild(mm)}问:新手求解flash as3.0 创建了一个mc,怎么用for语句把mc复制到舞台上,并且命名mc1,mc2,mc3。
【设计模式】策略模式与状态模式。
策略模式与状态模式在实现上有共同之处,都是把不同的情形抽象为统⼀的接⼝来实现,就放在⼀起进⾏记录。
2个模式的UML建模图基本相似,区别在于状态模式需要在⼦类实现与context相关的⼀个状态⾏为。
状态模式的的思想是,状态之间的切换,在状态A执⾏完毕后⾃⼰控制状态指向状态B。
状态模式是不停的切换状态执⾏。
策略模式的思想上是,考虑多种不同的业务规则将不同的算法封装起来,便于调⽤者选择调⽤。
策略模式只是条件选择执⾏⼀次。
策略模式1. Strategy: 定义所有⽀持的算法的公共接⼝抽象类.2. ConcreteStrategy: 封装了具体的算法或⾏为,继承于Strategy3. Context: ⽤⼀个ConcreteStrategy来配置,维护⼀个对Strategy对象的引⽤。
状态模式1. State: 抽象状态类,定义⼀个接⼝以封装与context的⼀个状态相关的⾏为2. ConcreteState: 具体状态,每⼀⼦类实现⼀个与Context的⼀个状态相关的⾏为3. Context: 维护⼀个ConcreteState⼦类的实例,这个实例定义当前的状态。
使⽤场景: 状态模式主要解决的是当控制⼀个对象状态转换的条件表达式过于复杂时的情况。
把状态的判断逻辑转移到表⽰不同状态的⼀系列类当中,可以把复杂的判断逻辑简化。
当⼀个对象的⾏为取决于它的状态,并且它必须在运⾏时刻根据状态改变它的⾏为时,就可以考虑使⽤状态模式了。
策略模式的Strategy类层次为Context定义了⼀系列的可供重⽤的算法或⾏为。
继承有助于析取出这些算法中的公共功能。
在实践中,我们发现可以⽤它来封装⼏乎任何类型的规则,只要在分析过程中听到需要在不同时间应⽤不同的业务规则,就可以考虑使⽤策略模式处理这种变化的可能性。
状态模式和策略模式的⽐较 两个模式的实现类图虽然⼀致,但是实现⽬的不⼀样! ⾸先知道,策略模式是⼀个接⼝的应⽤案例,⼀个很重要的设计模式,简单易⽤,策略模式⼀般⽤于单个算法的替换,客户端事先必须知道所有的可替换策略,由客户端去指定环境类需要哪个策略,注意通常都只有⼀个最恰当的策略(算法)被选择。
【AS3与设计模式】 Strategy Pattern (策略模式)
[ 2007-09-03 10:06:04 | 发布: N神 ]
字体大小: 大 | 中 | 小
关于这一系列的索引页和说明请点这里
/blog/article.asp?id=510
想直接下Strategy演示代码的点这里
先看一下定义吧
The Strategy Pattern: a famly of algorithms, encapsulates each one, and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it.
大概意思就是有一系列算法,把他们每个算法都分别封装起来,使他们可以互相替换。
策略模式可以让算法从客户端独立出来,算法的改变不会影响客户端
在网上很容易就可以古狗到策略模式的类图
每个算法都是一个具体的策略,图中
ConcreteStrategyA,ConcreteStrategyB,ConcreteStrategyC为3 个具体的算法,Strategy模式就是把一组具体的算法(策略)分别封装起来,并把这些封装起来的算法实现共同的一个接口 Strategy ,这个接口就是一个抽象的策略,我们的主类中拥有一个抽象策略的引用声明为Strategy接口类型,所有具体算法们都实现了抽接口中的方法AlgorithmInterface (),由于多态,所以我们可在我们的主类里直接调用抽象接口的方法AlgorithmInterface() ,这样做的好处就是我们可以在run time时使用setter方法改变具体的策略而不影响到客户的代码。
测试代码:
package {
import flash.display.Sprite;
import net.nshen.designpatterns.strategy.*;
public class designpatterns extends Sprite
{
public function designpatterns()
{
Test_Strategy()
}
public function Test_Strategy():void{
var context:Context=new Context();
//设置策略
context.strategy=new ConcreteStrategyA()
context.ContextInterface()
//runtime 更改策略B
context.strategy=new ConcreteStrategyB()
context.ContextInterface()
//runtime 更改策略C
context.strategy=new ConcreteStrategyC()
context.ContextInterface()
}
}
}
Context:
* 需要使用ConcreteStrategy提供的算法。
* 内部维护一个Strategy的实例。
* 负责动态设置运行时Strategy具体的实现算法。
* 负责跟Strategy之间的交互和数据传递。
package net.nshen.designpatterns.strategy
{
public class Context
{
private var _strategy:IStrategy
public function set strategy(p_strategy:IStrategy):void{ this._strategy=p_strategy;
}
public function ContextInterface():void{
this._strategy.AlgorithmInterface()
}
}
}
Strategy(抽象策略类):
* 定义了一个公共接口,各种不同的算法以不同的方式实现这个接口,Context 使用这个接口调用不同的算法,一般使用接口或抽象类实现。
package net.nshen.designpatterns.strategy
{
/**
*
*
* 抽象策略,可以为接口,也可以为一个抽象类,这里是接口
*
*/
public interface IStrategy
{
function AlgorithmInterface():void
}
}
ConcreteStrategy(具体策略类):
* 实现了Strategy定义的接口,提供具体的算法实现
具体策略A:
package net.nshen.designpatterns.strategy
{
public class ConcreteStrategyA implements IStrategy
{
public function AlgorithmInterface():void
{
trace("调用策略A")
}
}
}
具体策略B:
package net.nshen.designpatterns.strategy
{
public class ConcreteStrategyB implements IStrategy
{
public function AlgorithmInterface():void
{
trace("调用策略B")
}
}
}
具体策略C:
package net.nshen.designpatterns.strategy
{
public class ConcreteStrategyC implements IStrategy
{
public function AlgorithmInterface():void
{
trace("调用策略C")
}
}
}
完整代码点这里下载
在《head first design patterns》的例子中更把策略描述成行为(Behavior)的抽象,建议去看一下,由于各种各样的鸭子叫的方法和飞的方法各不相同,如下图,把鸭子的多种Fly行为和多种Quack行为独立出来,打包成两个策略包,分别实现两个抽象的接口FlyBehaviors 和 QuackBehaviors ,此时所有鸭子的父类Duck就是上面图中的Context,保存抽象策略的引用 flyBehavior , quackBehavior ,由于策略模式的好处,使得Duck的子类各种各样的鸭子可以run time选择自己相应的行为。