ImageVerifierCode 换一换
格式:DOCX , 页数:16 ,大小:57.28KB ,
资源ID:7765152      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/7765152.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(命令模式.docx)为本站会员(b****6)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

命令模式.docx

1、命令模式_command = $command; public function executeCommand() foreach($this-_command as $command) $command-execute(); public function removeCommand($command) $key = array_search($command, $this-_command); if($key != false) unset($this-_command$key); class Receiver /接收者(Receiver)角色 private $_name = null;

2、 public function _construct($name) $this-_name = $name; public function action() echo $this-_name. action; public function action1() echo $this-_name. action1; class ConcreteCommand implements Command /具体命令(ConcreteCommand)角色 private $_receiver; public function _construct($receiver) $this-_receiver

3、= $receiver; public function execute() $this-_receiver-action(); class ConcreteCommand1 implements Command /具体命令(ConcreteCommand)角色 private $_receiver; public function _construct($receiver) $this-_receiver = $receiver; public function execute() $this-_receiver-action1(); class ConcreteCommand2 imple

4、ments Command /具体命令(ConcreteCommand)角色 private $_receiver; public function _construct($receiver) $this-_receiver = $receiver; public function execute() $this-_receiver-action(); $this-_receiver-action1(); $objRecevier = new Receiver(No.1);$objRecevier1 = new Receiver(No.2);$objRecevier2 = new Receiv

5、er(No.3);$objCommand = new ConcreteCommand($objRecevier);$objCommand1 = new ConcreteCommand1($objRecevier);$objCommand2 = new ConcreteCommand($objRecevier1);$objCommand3 = new ConcreteCommand1($objRecevier1);$objCommand4 = new ConcreteCommand2($objRecevier2);$objInvoker = new Invoker();$objInvoker-s

6、etCommand($objCommand); $objInvoker-setCommand($objCommand1);$objInvoker-executeCommand();-$objInvoker-removeCommand($objCommand1);$objInvoker-executeCommand();-$objInvoker-setCommand($objCommand2);$objInvoker-setCommand($objCommand3);$objInvoker-setCommand($objCommand4);$objInvoker-executeCommand()

7、;结果:No.1 actionNo.1 action1-No.1 action-No.1 actionNo.2 actionNo.2 action1No.3 actionNo.3 action1命令模式涉及到五个角色,它们分别是: 客户端(Client)角色:创建一个具体命令(ConcreteCommand)对象并确定其接收者。抽象命令(Command)角色:声明了一个给所有具体命令类的抽象接口。具体命令(ConcreteCommand)角色:定义一个接收者和行为之间的弱耦合;实现execute()方法,负责调用接收者的相应操作。execute()方法通常叫做执行方法。请求者(Invoker)

8、角色:负责调用命令对象执行请求,相关的方法叫做行动方法。接收者(Receiver)角色:负责具体实施和执行一个请求。任何一个类都可以成为接收者,实施和执行请求的方法叫做行动方法。模式分析1.命令模式的本质是对命令进行封装,将发出命令的责任和执行命令的责任分割开。2.每一个命令都是一个操作:请求的一方发出请求,要求执行一个操作;接收的一方收到请求,并执行操作。3.命令模式允许请求的一方和接收的一方独立开来,使得请求的一方不必知道接收请求的一方的接口,更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。4.命令模式使请求本身成为一个对象,这个对象和其他对象一样可以被存储

9、和传递。5.命令模式的关键在于引入了抽象命令接口,且发送者针对抽象命令接口编程,只有实现了抽象命令接口的具体命令才能与接收者相关联。模式优点1.降低对象之间的耦合度。2.新的命令可以很容易地加入到系统中。3.可以比较容易地设计一个组合命令。4.调用同一方法实现不同的功能模式缺点使用命令模式可能会导致某些系统有过多的具体命令类。因为针对每一个命令都需要设计一个具体命令类,因此某些系统可能需要大量具体命令类,这将影响命令模式的使用。缺点:如果产品太多,会导致命令大量增多。造成代码量增多,有点和工厂方法模式比较相像 最后说一下命令模式的缺点,那就是命令如果很多,开发起来就要头疼了。特别是很多简单的命

10、令,实现起来就几行代码的事,而使用命令模式的话,不用管命令多简单,都需要写一个命令类来封装。适用环境1.系统需要将请求调用者和请求接收者解耦,使得调用者和接收者不直接交互。2.系统需要在不同的时间指定请求、将请求排队和执行请求。3.系统需要支持命令的撤销(Undo)操作和恢复(Redo)操作。4.系统需要将一组操作组合在一起,即支持宏命令。命令模式的优点 更松散的耦合命令模式使得发起命令的对象客户端,和具体实现命令的对象接收者对象完全解耦,也就是说发起命令的对象完全不知道具体实现对象是谁,也不知道如何实现。更动态的控制命令模式把请求封装起来,可以动态地对它进行参数化、队列化和日志化等操作,从而

11、使得系统更灵活。很自然的复合命令命令模式中的命令对象能够很容易地组合成复合命令,也就是宏命令,从而使系统操作更简单,功能更强大。更好的扩展性由于发起命令的对象和具体的实现完全解耦,因此扩展新的命令就很容易,只需要实现新的命令对象,然后在装配的时候,把具体的实现对象设置到命令对象中,然后就可以使用这个命令对象,已有的实现完全不用变化。 命令模式总结: 它能很容易的维护所有命令的集合。 它可以很方便的实现撤销和恢复命令。 可以很方便的将每个执行记录日志。 最重要的就是将发起者与实现者分离。命令模式有以下优点:1.命令模式将调用操作的请求对象与知道如何实现该操作的接收对象解耦。2.具体命令角色可以被

12、不同的请求者角色重用。3.你可将多个命令装配成一个复合命令。4.增加新的具体命令角色很容易,因为这无需改变已有的类。命令模式的以下适用环境:1.需要抽象出待执行的动作,然后以参数的形式提供出来类似于过程设计中的回调机制。而命令模式正是回调机制的一个面向对象的替代品。2.在不同的时刻指定、排列和执行请求。一个命令对象可以有与初始请求无关的生存期。3需要支持取消操作。4.支持修改日志功能。这样当系统崩溃时,这些修改可以被重做一遍。5.需要支持事务操作。Command模式通常可应用到以下场景: 1 Multi-level undo(多级undo操作) 如果系统需要实现多级回退操作,这时如果所有用户的

13、操作都以command对象的形式实现,系统可以简单地用stack来保存最近执行的命令,如果用户需要执行undo操作,系统只需简单地popup一个最近的command对象然后执行它的undo()方法既可。 2 Transactional behavior(原子事务行为) 借助command模式,可以简单地实现一个具有原子事务的行为。当一个事务失败时,往往需要回退到执行前的状态,可以借助command对象保存这种状态,简单地处理回退操作。 3 Progress bars(状态条) 假如系统需要按顺序执行一系列的命令操作,如果每个command对象都提供一个 getEstimatedDuration

14、()方法,那么系统可以简单地评估执行状态并显示出合适的状态条。 4 Wizards(导航) 通常一个使用多个wizard页面来共同完成一个简单动作。一个自然的方法是使用一个command对象来封装wizard过程,该command对象在第一个wizard页面显示时被创建,每个wizard页面接收用户输入并设置到该command对象中,当最后一个wizard页面用户按下“Finish”按钮时,可以简单地触发一个事件调用execute()方法执行整个动作。通过这种方法,command类不包含任何跟用户界面有关的代码,可以分离用户界面与具体的处理逻辑。 5 GUI buttons and menu

15、items(GUI按钮与菜单条等等)-软件工具视图 Swing系统里,用户可以通过工具条按钮,菜单按钮执行命令,可以用command对象来封装命令的执行。 6 Thread pools(线程池) 通常一个典型的线程池实现类可能有一个名为addTask()的public方法,用来添加一项工作任务到任务队列中。该任务队列中的所有任务可以用command对象来封装,通常这些command对象会实现一个通用的接口比如java.lang.Runnable。 7 Macro recording(宏纪录) 可以用command对象来封装用户的一个操作,这样系统可以简单通过队列保存一系列的command对象的

16、状态就可以记录用户的连续操作。这样通过执行队列中的command对象,就可以完成Play back操作了。 8 Networking 通过网络发送command命令到其他机器上运行。 9 Parallel Processing(并发处理) 当一个调用共享某个资源并被多个线程并发处理时。11.5命令模式近几年,我的每个项目几乎都用到了命令模式。命令模式最初来源于图形化用户界面设计,但现在广泛应用于企业应用设计,特别促进了控制器(请求和分发处理)和领域模型(应用逻辑)的分离。说得更简单一点,命令模式有助于系统更好地进行组织,并易于扩展。11.5.1问题所有系统都必须决定如何响应用户请求。在PHP中

17、,这个决策过程通常是由分散的各个PHP页面来处理。比如当用户访问一个PHP页面(如feedback.php)时,用户明确地告诉系统他所要求的功能和接口。但现在PHP开发者日益倾向于在设计系统时采用单一入口的方式(我们将在下一章中讨论)。无论是多个入口还是单个入口,接收者都必然将用户请求委托给一个更加关注于应用逻辑的层来进行处理。这个委托在用户请求不同页面时尤为重要。如果没有委托,代码重复将会不可避免地蔓延在整个项目中。让我们想象一下,假设一个有很多任务要执行的项目,需要允许某些用户登录,某些用户可以提交反馈。我们可以分别创建login.php和feedback.php页面来处理这些任务,并实例

18、化专门的类以完成任务。不过遗憾的是,系统中的用户界面很难被精确地一一对应到系统任务。比如我们可能要求每个页面都有登录和反馈的功能。如果页面必须处理很多不同的任务,就应该考虑将任务进行封装。封装之后,向系统增加新任务就会变得简单,并且可以将系统中的各部分分离开来。当然,这时我们可以使用命令模式。11.5.2实现命令对象的接口极为简单,因为它只要求实现一个方法execute()。在图11-8中,Command被定义为一个抽象类。同样简单地,它也可以被定义为接口。我喜欢将它定义为抽象类,因为有时基类也可以为它的衍生对象提供有用的公共功能。命令模式由3部分组成:实例化命令对象的客户端(client )

19、、部署命令对象的调用者(invoker)和接受命令的接收者(receiver)。通过客户端,接收者可以在命令对象的构造方法中被传递给命令对象,或者通过某种工厂对象被获得。相对而言,我更喜欢后一种办法,它可以保持构造方法参数清晰明了,而且所有的Command对象都可以用完全相同的方式实例化。让我们创建一个具体的Command类:abstract class Commandabstract function execute(CommandContext $context);class LoginCommand extends Command function execute(CommandCont

20、ext $context) $manager=Registry:getAccessManager(); $user=$context-get(username); $pass=$context-get(pass); $user_obj=$manager-login($user,$pass); if(is_null($user_obj) $context-setError($manager-getError(); return false; $context-addParam(user,$user_obj); return true; LoginCommand被设计为与AccessManager

21、(访问管理器)对象一起工作。AccessManager是一个虚构出来的类,它的任务就是处理用户登录系统的具体细节。注意Contend: :execute ( )方法要求使用CommandContext对象作为参数J2EE核心模式中将其描述为RequestHelper。通过CommandContext 机制,请求数据可被传递给Command对象,同时响应也可以被返回到视图层。以这种方式使用对象是很有好处的,因为我们可以不破坏接口就把不同的参数传递给命令对象。从本质上说,CommandContext 只是将关联数组变量包装而成的对象,但我们仍会经常扩展它来执行额外的任务。下面是一个简单的Comma

22、ndContext实现:class CommandContext private $params=array(); private $error=; function _construct() $this-params=$_REQUEST; function addParam($key,$val) $this-params$key=$val; function get($key) return $this-params$key; function setError($error) $this-error=$error; function getError() return$this-error

23、; 因此通过使用CommandContext对象,LoginCommand能够访问请求数据:提交的用户名和密码。我们使用了一个简单的类Registry,它带有用于生成通用对象的静态方法,可以返回LogicCommand所需要的AccessManager对象。如果AccessManager报告一个错误,则LoginCommand保存错误信息到CommandContext对象中以供表现层使用并返回false。如果一切正常,LoginCommand只返回true。注意command对象不应该执行太多的逻辑。它们应该负责检查输入、处理错误、缓存对象和调用其他对象来执行一些必要的操作。如果你发现应用逻辑

24、过多地出现在Command类中,通常需要考虑重构代码。这样的代码会导致代码重复,因为它们不可避免地会在不同的Command类中被复制粘贴。你至少需要考虑这些应用逻辑的功能应该属于哪部分代码。最好把这样的代码迁移到业务对象中或者放入一个外观层中。现在我们仍然缺少客户端代码(即用于创建命令对象的类)及调用者类(使用生成的命令的类)。在一个Web项目中,选择实例化哪个命令对象的最简单的办法是根据请求本身的参数来决定。下面是一个简化的客户端代码:class CommandNotFoundException extends Exception class CommandFactory private s

25、tatic $dir=commands; static function getCommand($action=Default) if(preg_match(/W/,$action) throw new Exception(illegal characters in action); $class=UCFirst(strtolower($action).commands; $file=self:$dir.DIRECTOR_SEPARATOR .$class.php; if(!file_exists($file) throw new CommandNotFoundException(could

26、not find $file ); require_once($file); if(!class_exists($class) throw new CommandNotFoundException(not $class class located); $cmd=new $class(); return $cmd; CommandFacotry类在commands目录里查找特定的类文件。文件名是通过CommandContext对象的$action参数来构造的,该参数是从请求中被传到系统中的。如果文件和类都存在,那么会返回命令对象给调用者。我们可以在这里添加更多的错误检查,比如保证找到的类是Com

27、mand类的子类,保证构造方法没有参数等,但目前的版本对我们来说已经足够说明问题。这种方式的优点是你可以随时将新的Command类添加到commands目录下,然后系统便立即支持它了。下面是一个简单的调用者:class Controller private $context; function _construct() $this-context=new CommandContext(); function getContext() return $this-context; function process() $cmd=CommandFactory:getCommand($this-con

28、text-get(action); if(!$cmd-execute($this-context) /处理失败 else /成功 /现在分发视图 $controller=new Controller();/伪造用户请求$context=$controller-getContext();$context-addParam(action,login);$context-addParam(username,bob);$context-addParam(pass,tzddles);$controller-process();19.php?phpabstract class Command abstract function execute(CommandContext $context);class LoginCommand extends Command /命令接收者 function execute(CommandContext $context) $manager=Registry:getAccessManager(); $user=$co

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1