大白话讲解设计模式之命令模式

11 篇文章 0 订阅
2 篇文章 0 订阅

初衷:

看了一些命令模式的博客,仍然不知道如何实现一个命令模式,如何设计,以及为何这么设计,本文通过一个例子来说明命令模式的设计过程以及这么设计的原因。

命令模式分解:

命令模式从组成上分为:

  • 命令(Command)
  • 调用者 (invoker)
  • 客户端 (client)
  • 命令接收者 (receiver)

其中,命令的具体实现类可以有多个,即可以有多个命令。
调用者为统一处理命令,让命令接收者执行命令,只有一个。
客户端为发起命令的主体。
命令接收者为具体的命令执行者。

接下来,我们看看具体的例子来理解何为命令模式,如何设计。
eg:PM要给RD提出各种各样的需求和修改,但需要在需求评审会上进行需求评审,由Leader拍板是不是做,PM说,RD,请实现APP的界面颜色随着用户手机壳颜色的变化而变化,Leader一听,有意思,做起来,然后给RD下达了命令,RD一看需求无能为力,将无法实现的结果告诉Leader,Leader将最终结果反馈给PM。
在这个例子中,PM(客户端)发出了命令,命令包括了两部分内容:

  1. RD(命令的接收者)
  2. APP界面颜色随着手机壳颜色变化而变化(接收者需要做的具体操作)

然后PM(客户端)不直接去找RD(receiver),需要找Leader(invoker)进行需求评审,Leader(invoker)需要作出一些判断或者前置后置处理,再让RD(接收者)执行具体的命令。

如何设计命令模式

这就是一个命令模式的例子,通过例子我们可以思考,如何设计命令模式:
参考上述命令模式的组成,我们分别设计:

设计命令:

有例子可以看出,一个具体的命令包括了具体的命令接收者和具体的执行操作,又由于可以有很多个命令,所以需要将命令进行抽象化,即接口或者抽象类:

public abstract class Command {
     //每个命令类都必须有一个执行命令的方法
     public abstract void execute();
}

具体的命令类需要包括两个部分,一是实现抽象类的方法,即命令的具体操作,二是新增命令的执行者属性。

public class ConcreteCommand extends Command {
     //对哪个Receiver类进行命令处理
     private Receiver receiver; 
     //构造函数传递接收者
     public ConcreteCommand(Receiver _receiver){
             this.receiver = _receiver;
     }
     //必须实现一个命令
     public void execute() {
             //业务处理
             this.receiver.doSomething();
     }
}

设计调用者:

根据上述的Leader(invoker),他需要知道PM的具体命令,所以他需要有一个命令的成员变量,然后他需要经过一些操作后让RD(接收者)开始执行命令,所以他一个执行方法。

public class Invoker {
     private Command command;
     //设置命令
     public void setCommand(Command _command){
             this.command = _command;
     }
     //执行命令
     public void action(){
             this.command.execute();
     }
}

设计接收者:

RD(接收者)负责执行命令,需要对外暴露自己的能力,比如RD需要让PM知道自己会写bug,这样PM有写bug的需求才会给RD发出命令。又因为有好多RD,所以需要抽象一下,每个具体的RD继承该类。

public abstract class Receiver {
     //抽象接收者,定义每个接收者都必须完成的业务
     public abstract void doSomething();
}

设计客户端:

PM(客户端)是一个调用者,他负责发出一些无理的需求(命令,包括接收者和具体操作),然后告诉Leader(incoker),由Leader反馈给他最后的执行结果

public class Client {
     public static void main(String[] args) {
             //首先声明调用者Invoker
             Invoker invoker = new Invoker();
             //定义接收者
             Receiver receiver = new ConcreteReciver();
             //定义一个发送给接收者的命令
             Command command = new ConcreteCommand(receiver);
             //把命令交给调用者去执行
             invoker.setCommand(command);
             invoker.action();
     }
}

优缺点

通过上面的设计可以看出,优点就是:解决了命令发起者和实现者直接的高耦合的关系,新添加一个命令也很容易。缺点是: 可能会因为命令的增多而导致命令类过多。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值