贵港有网站建设的公司吗,深投建设深圳有限公司,网络营销流程,西部数码网站管理助手4.0 破解版转载自 命令模式#xff08;Command#xff09;的两种不同实现命令模式#xff08;Command#xff09;#xff1a;将一个请求封装成一个对象#xff0c;使得你用不同的请求把客户端参数化#xff0c;对请求排队或者记录请求日志#xff0c;可以提供命令的撤销和恢复功能…转载自 命令模式Command的两种不同实现命令模式Command将一个请求封装成一个对象使得你用不同的请求把客户端参数化对请求排队或者记录请求日志可以提供命令的撤销和恢复功能。命令模式顾名思义来理解即可就是客户端发布一个命令也就是“请求”而这个命令是已经被封装成一个对象的。即这个命令对象的内部可能已经指定了该命令具体被谁负责执行。就像开发经理从客户那边获取对方的需求命令客户在描述具体的需求可以决定是否明确指出该需求的执行方。命令模式的通用类图如下 上图中Invoker 类就相当于开发经理ConcreteCommand 类是具体的命令它继承自抽象命令类 Command 类该抽象类中定义了每个命令被执行的方法 execute() 。Receiver 抽象类定义了对每一个具体的命令的执行方法 action() ,一旦接收到命令则立即行动。这里应该注意的是每个具体的命令类都必须指定该命令的接收者否则这命令发布了也没相应的人来完成那就没戏了。具体代码实现如下命令接收者相关类//抽象接收者定义了每个接收者应该完成的业务逻辑 abstract class AbstractReceiver { public abstract void doJob(); } // 具体接收者01实现自己真正的业务逻辑 class Receiver01 extends AbstractReceiver { public void doJob() { System.out.println(接收者01 完成工作 ...\n); } } // 具体接收者02实现自己真正的业务逻辑 class Receiver02 extends AbstractReceiver { public void doJob() { System.out.println(接收者02 完成工作 ...\n); } }
命令类// 抽象命令类定义了每个具体命令被执行的入口方法execute() abstract class AbstractCommand { public abstract void execute(); } // 具体命令类01通过构造函数的参数决定了该命令由哪个接收者执行 class Command01 extends AbstsractCommand { private AbstractReceiver receiver null; public Command01(AbstractReceiver receiver) { this.receiver receiver; } public void execute() { System.out.println(命令01 被发布 ...); this.receiver.doJob(); } } // 具体命令类02通过构造函数的参数决定了该命令由哪个接收者执行 class Command02 extends AbstractCommand { private AbstractReceiver receiver null; public Command02(AbstractReceiver receiver) { this.receiver receiver; } public void execute() { System.out.println(命令02 被发布 ...); this.receiver.doJob(); } }
调用者类// 调用者负责将具体的命令传送给具体的接收者 class Invoker { private AbstractCommand command null; public void setCommand(AbstractCommand command) { this.command command; } public void action() { this.command.execute(); } }
测试类//测试类 public class Client { public static void main(String[] args) { // 创建调用者 Invoker invoker new Invoker(); // 创建一个具体命令并指定该命令被执行的具体接收者 AbstractCommand command01 new Command01(new Receiver01()); // 给调用者发布一个具体命令 invoker.setCommand(command01); // 调用者执行命令其实是将其传送给具体的接收者并让其真正执行 invoker.action(); AbstractCommand command02 new Command01(new Receiver02()); invoker.setCommand(command02); invoker.action(); } }
测试结果命令01 被发布 ...接收者01 完成工作 ...命令02 被发布 ...接收者02 完成工作 ...如上面测试中输出的结果我们知道在客户端中每次声明并创建一个具体的命令对象时总要显式地将其指定给某一具体的接收者也就是命令的最终执行者这似乎不太灵活在现实中有些命令的发布也确实不是预先就指定了该命令的接收者的。我们可以修改一下类图使得客户端在有必要的时候才显式地指明命令的接收者如下较之第一个通用类图这里的客户 Client 类不直接与接收者 Receiver 类相关而仅仅与调用者 Invoker 类有联系客户发布下来的一个命令或者请求只需要到了调用者Invoker 这里就停止了具体怎么实现不必对客户公开由调用者分配即可。这里的 Command 抽象类将子类中指定具体接收者的构造函数的逻辑提取出来由具体子类提供通过调用父类构造函数的无参、有参构造函数来实现。主要修改的是命令相关的类。 具体逻辑请看下面的代码实现命令类/* * 抽象命令类使用构造函数的传入参数预先内定具体接收者 若想使用其他接收者可在子类的构造函数中传入 */ abstract class AbstractCommand { protected AbstractReceiver receiver null; public AbstractCommand(AbstractReceiver receiver) { this.receiver receiver; } public abstract void execute(); } // 具体命令类01提供无参、有参两种构造函数 class Command01 extends AbstractCommand { // 使用无参构造函数来默认使用的具体接收者 public Command01() { super(new Receiver01()); } // 使用有参构造函数来指定具体的接收者 public Command01(AbstractReceiver receiver) { super(receiver); } public void execute() { System.out.println(命令01 被发布 ...) this.receiver.doJob(); } } // 具体命令类02提供无参、有参两种构造函数 class Command02 extends AbstractCommand { // 使用无参构造函数来默认使用的具体接收者 public Command02() { super(new Receiver02()); } // 使用有参构造函数来指定具体的接收者 public Command02(AbstractReceiver receiver) { super(receiver); } public void execute() { System.out.println(命令02 被发布 ...) this.receiver.doJob(); } }
修改后的测试类// 测试类 public class Client { public static void main(String[] args) { // 创建调用者 Invoker invoker new Invoker(); // 创建一个具体命令并指定该命令被执行的具体接收者 // AbstractCommand command01 new Command01(new Receiver01()); AbstractCommand command01 new Command01(); // 给调用者发布一个具体命令 invoker.setCommand(command01); // 调用者执行命令其实是将其传送给具体的接收者并让其真正执行 invoker.action(); // AbstractCommand command02 new Command01(receiver02); AbstractCommand command02 new Command02(); invoker.setCommand(command02); invoker.action(); System.out.println(\n设置命令01由接收者02执行...); command01 new Command01(new Receiver02()); invoker.setCommand(command01); invoker.action(); } }
测试结果命令01 被发布 ...接收者01 完成工作 ...命令02 被发布 ...接收者02 完成工作 ...设置命令01由接收者02执行...命令01 被发布 ...接收者02 完成工作 ...此时在客户端中我们不指明一个命令的具体接收者执行者也同样可以达到第一种实现方法中的效果。此外客户也可以显式指出具体接收者就像上面那样。命令模式的优点1、 调用者与接收者没有任何的依赖关系它们时通过具体的命令的存在而存在的2、 若有多个具体命令只要扩展 Command 的子类即可同样地具体接收者也可以相对应地进行扩展命令模式的缺点其实上面优点中第2点在一定场景中也会变成缺点。如果具体的命令有很多个那么子类就必然会暴增、膨胀。但是上面的具体代码实现中这种设计似乎也不太乐观原因是每一个具体的命令都是由一个具体的接收者来执行的在多交互的场景中这显然是太理想化的。于是我想到了中介者模式Mediator中最主要的 Mediator 类中预先地注册了业务中需要交互的同事类的对象接下来每一次交互逻辑都交给 Mediator 来“暗箱”操作。根据上一段的想法我们可以在抽象命令 Command 类中预先注册一定数量的具体接收者那么具体命令中就可以决定是否要在多个接收者中进行协作完成了这种协作的代码逻辑则应该写在覆盖父类的execute() 方法中而在 execute() 方法中又可以运用模板方法模式Template Method进行设计。