actionscript-3 – 命令模式和AS3
只是好奇你们如何解决封装命令的问题.您是否为每个命令创建一个单独的类?或者还有另一种方式(没有大量的课程)?
请注意,我正面临着动作脚本3的问题. Upd:更确切地说,我想知道如何组织命令相关的机器(例如每个命令的类). 先感谢您! 解决方法
命令模式是关于分离三个不同类别的对象之间的关注点:
>祈求者 正如wvxvw所指出的那样,通常意味着你有一个实现ICommand的TON类,它实际上只是作为调用接收器上方法的代理工作 – 这是Java所必需的.随着时间的推移,这会变得有点难以管理. 但是让我们看一些代码,我将按照示例代码介绍找到的命令模式的基础知识here,但为了清晰起见略有简化: 所以首先是接收器: // Receiver public interface IStarShip { function engage():void; function makeItSo():void; function selfDestruct():void; } public class Enterprise implements IStarShip { public function Enterprise() { } public function engage():void { trace(this,"Engaging"); } public function makeItSo():void { trace(this,"Making it so"); } public function selfDestruct():void { trace(this,"Self Destructing"); } } 和调用者: // invoker public class CaptPicard { private var _command:ICommand; public function CaptPicard() { } public function set command(cmd:ICommand):void { this._command = cmd; } public function issueCommand():void { } } 最后一些命令: // command public interface ICommand { function execute():void; } public class EngageCommand implements ICommand { private var receiver:IStarShip public function EngageCommand(receiver:IStarShip) { this.receiver = receiver; } public function execute():void { receiver.engage(); } } public class SelfDestructCommand implements ICommand { private var receiver:IStarShip public function SelfDestructCommand(receiver:IStarShip) { this.receiver = receiver; } public function execute():void { receiver.selfDestruct(); } } public class MakeItSoCommand implements ICommand { private var receiver:IStarShip public function MakeItSoCommand(receiver:IStarShip) { this.receiver = receiver; } public function execute():void { receiver.makeItSo(); } } 我们可以通过以下方式来解决这些问题: var enterprise:Enterprise = new Enterprise; var picard:CaptPicard = new CaptPicard(); picard.command = new SelfDestructCommand(enterprise); picard.issueCommand(); 到目前为止,它与示例代码紧密相关,并且是ActionScript中命令模式的非常标准的实现.但是,现在我们有三个ICommand实现,并且随着接收器可以增加的数量增加,编排模式所需的命令数量也会增加. 如果我们开始检查Command本身,除了告诉接收器做一些工作之外,它并没有做太多其他事情.正如wvxvw暗示的那样,动作脚本中已经有了这样的功能:一流的功能. 让我们看看可能的实现,以减少你需要浮动的ICommand的实现数量,而不需要改变你的模式. 让我们说我们制作了一个通用类型的命令,让我们说: public class GenericCommand implements ICommand { private var worker:Function; public function GenericCommand(worker:Function) { this.worker = worker; } public function execute():void { this.worker.call(); } } 请注意,我们的新类型仍然实现ICommand,但它不接受直接绑定到某个实现,而是接受一个worker来做一些工作.它不会立即执行它,它只是坚持它并等待其他东西使它运动. 然后我们可以将代码切换为这样的代码: var enterprise:Enterprise = new Enterprise; var picard:CaptPicard = new CaptPicard(); picard.command = new GenericCommand(function() { enterprise.selfDestruct(); }); picard.issueCommand(); picard.command = new GenericCommand(function() { enterprise.engage(); }); picard.issueCommand(); picard.command = new GenericCommand(function() { enterprise.makeItSo(); }); picard.issueCommand(); 使用这一个GenericCommand,我们可以将所有命令展开到这个新模式中(或者在它们之间混合和匹配). 但是如果你仔细观察,你可以看到,通过使用它,我们通过引用封闭的变量企业将一个通用命令紧密地耦合到IStarShip,或许更令人担心的是,如果我们不小心,我们可以创造一吨这些关闭.它们都需要在某些时候进行垃圾收集,这可能会影响性能,或者更糟糕的是导致内存泄漏. 我们可以将这一层更多地分离,使其更具动态性.我们可以使用工厂模式来帮助动态生成命令,而不是直接关闭到本地变量企业.考虑一下: public class StarShipCommandFactory { private var worker:Function; public function StarShipCommandFactory(worker:Function) { this.worker = worker; } public function to(receiver:IStarShip):ICommand { return new GenericCommand(function() { worker.call(undefined,receiver); }); } } 然后我们可以使用它来创建一个命令工厂来创建这些命令.就像是: var enterpriseA:Enterprise = new Enterprise(); var enterpriseB:Enterprise = new Enterprise(); var picard:CaptPicard = new CaptPicard(); var selfDestuctor:StarShipCommandFactory = new StarShipCommandFactory(function(starShip:IStarShip):void { starShip.selfDestruct(); } ); var blowUpA:ICommand = selfDestructor.to(enterpriseA); var blowUpB:ICommand = selfDestructor.to(enterpriseB); picard.command = blowUpA; picard.issueCommand(); picard.command = blowUpB; picard.issueCommand(); 这将减少需要生成的静态类的数量,以利用属性第一类函数的动态创建的对象,但仍然应用相同的一般概念. 实际上,使用这种模式,您可以构建非常复杂的命令,代理多个接收器上的多个动作,这可能是一个非常强大的功能. 你为什么要使用ICommand的传统实现呢? 坚持传统模式的最大原因之一是易于序列化.因为对象是显式的,所以它们很容易序列化.所以,假设你有一堆Vector.< ICommand>.您可以轻松地序列化它们,将它们写出来,然后再重新加载它们并按顺序重放它们,并且应该处于与您完全相同的状态.动态生成的对象就像我之前描述的对象一样有点棘手 – 不是不可能,只是比较棘手. 如果您担心维护大量映射到接收器操作的ICommands,那么在过去我使用元编程来解决这个问题.使用ruby / python解析一定数量的文件,并自动生成ICommand映射.它们很多时候都是相当天真的实现,它们是自动化的主要候选者. 无论如何,这些是我对这个问题的看法.你可以做很多事情来帮助简化你的代码 – 我刚刚触及了表面.您的里程可能会有所不同 – 请记住:“找到解决问题的模式,而不是反过来” – 但也许您可以从中收集一些有用的信息. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
- ruby-on-rails – 获取fields_for以使用has_many关系
- 工作流模型分析(3)——流程发散聚合模型
- c – std :: vector push_back(Object())和push_back(new O
- c – 缓冲到硬盘
- xml – 如何使用XSLT转换NEWLINE?
- [swift]-数组的使用
- xcodebuild,缺少iOS模拟器sdk
- End-to-End Training of Hybrid CNN-CRF Models for Stereo
- 在Clojure中的XML文件上插入拉链树
- c# – 在ServiceStack中是否可以模拟Request.OriginalReque