浅谈设计模式:命令模式(Command Pattern)

热爱生活、享受娱乐、专注技术,欢迎关注微信公众号QGer,我们一起见证成长!

什么是命令模式?

官方解释:encapsulate a request under an object as a command and pass it to invoker object. Invoker object looks for the appropriate objectwhich can handle this command and pass the command to the corresponding object and that object executes the command。 封装一个请求对象作为一个命令并传递给调用器(命令发送者)对象。调用期对象寻找合适的能处理这条命令的对象并传递这条命令到应答(命令接受者)对象中,,接着该对象执行这条命令.

通俗解释:将一条命令封装成一个(请求)对象,定义一个命令调用器(发送者),一个命令执行器(接受者),将命令与命令接受者进行关联,并且由命令发送者来承载这条命令(一个命令调用器可承载多条命令),当客户端需要下达某个命令时,通过命令发送者调用相关命令即可。

为什么使用命令模式?

如何使用命令模式? 命令模式的UML图如下:

各个组件解释说明:

命令模式使用范围: 1、当一个场景中具有请求–>响应的功能,并且请求种类不少,希望响应功能对客户端透明。 2、当一个场景中,需要根据请求操作参数对象执行某些操作。 3、当你希望一个请求对象的创建和执行不在同一个时间。即命令创建后不用马上使用,在需要的时候使用。 4、当一个场景中你需要支持回滚、恢复、记录等功能时。

应用实例: 现在我们有这么一个场景,还记得之前Builder模式的例子吗,我们构造出寒冰射手这个Role之后,我们要发出命令来让英雄释放技能呀,我们可以这么做: 1、我们先抽象出一个Command接口,定义一个执行命令的接口。接着再抽象出Role接口,定义了QWER四个技能的释放方法接口。并用HanBingRole实现这一接口及技能释放方法。

interface Command {();}{void QSkill();void WSkill();void ESkill();void RSkill();}{() {System.out.println(“冰霜射击!!!”);}() {System.out.println(“万箭齐发!!!”);}() {System.out.println(“鹰击长空!!!”);}() {System.out.println(“魔法水晶箭”);}}

2、抽象完毕,那么我们需要定义具体的命令类,并与命令接受者(Role)相依赖,让接受者自己来执行命令的具体操作(role.XSkill())。

{private Role role;public QSkillCommand(Role role) {this.role = role;}() {role.QSkill();}}{private Role role;public WSkillCommand(Role role) {this.role = role;}() {role.WSkill();}}{private Role role;public QSkillCommand(Role role) {this.role = role;}() {role.ESkill();}}{private Role role;public QSkillCommand(Role role) {this.role = role;}() {role.RSkill();}}

3、具体命令和接收者都定义好了,接下来我们需要一个命令发送者(Invoker),由于具体命令较多,此处可定义一个技能类型枚举SkillType(QWER),并在Invoker定义一个map,让客户端决定技能类型与具体命令的关联。

enum SkillType {QSKILL,WSKILL,ESKILL,RSKILL}public class SKillInvoker {private Map<SkillType, Command> commandMap;SKillInvoker(Map<SkillType, Command> commandMap) {this.commandMap = commandMap;}(){commandMap.get(SkillType.QSKILL).excute();}(){commandMap.get(SkillType.WSKILL).excute();}(){commandMap.get(SkillType.ESKILL).excute();}(){commandMap.get(SkillType.RSKILL).excute();}}public class client {(String[] agrs) {HanBingRole hanBingRole = new HanBingRole();Map<SkillType, Command> commandMap = new HashMap<>();commandMap.put(SkillType.QSKILL, new QSkillCommand(hanBingRole));commandMap.put(SkillType.WSKILL, new WSkillCommand(hanBingRole));commandMap.put(SkillType.ESKILL, new ESkillCommand(hanBingRole));commandMap.put(SkillType.RSKILL, new RSkillCommand(hanBingRole));SKillInvoker sKillInvoker = new SKillInvoker(commandMap);sKillInvoker.castQSkill();sKillInvoker.castWSkill();sKillInvoker.castESkill();sKillInvoker.castRSkill();}}

此处HanBingRole的其他属性以及实例化方式我为简明起见做了简化,并没有使用Builder模式,实际开发中,HanBingRole可能是用其他的创建型模式进行实例化,创建型模式的具体用法可阅读我的前几篇文章,另外,此处技能类型与命令的映射也是用了最直接的方法,实际开发中,可能使用配置方式或其他易修改可拓展的方式来实现。

或者在河边放下一盏写着心愿的河灯,祝愿一切安好。

浅谈设计模式:命令模式(Command Pattern)

相关文章:

你感兴趣的文章:

标签云: