设计模式->行为型模式->命令模式

1.定义:将一个请求封装成一个对象,从而可以用不同的请求对客户进行参数化;对请求排队或者记录请求日志以及支持可撤销的操作

2.UML


3.涉及角色

1.抽象命令角色:定义了所有需要执行的命令即命令集体的行为eg:执行,回滚,撤销等

2.抽象接接收者角色:接受者需要处理对应的业务逻辑,知道如何执行一个请求相关的操作

3.具体命令角色:持有接收者的实例,调用接收者的具体操作完成命令的执行,也就是说具体命令知道哪个接收者能够执行该命令。它们之间存在1对1的关系,而职责链模式是不知道具体是哪个对象处理了对应的请求,同时请求来时需要从链首执行到链尾。

4.具体接收者角色:知道如何具体的实施和执行某个具体的命令,即某个具体命令对应的具体的业务逻辑

5.调用者角色:接受命令并执行,持有抽象命令角色实例

4.优点

1.容易设计一个命令队列

2.将命令记录到日志中,在必要的时候可以通过日志进行回滚操作

3.允许接收者决定是否否决当前的命令

4.可以在需要的时候撤销/重做命令且比较容易实现

5.方便新命令/新接收者的扩展,只需要实现具体的接口,高层模块和具体的命令以及接收者没有严重耦合

6.将请求操作的对象和知道怎么具体操作对象分割

7.实现调用者和接收者之间的解耦,调用者之需要知道命令而不需要知道具体的接收者如何处理

5.缺点

当抽象命令的子类较多时,可能会产生较多的子类。此时可以采用和其他模式配合使用eg:和职责链模式结合实现命令族解析任务。和模版方法模式结合减少子类的膨胀

6.使用场景
1.对请求排队或者记录日志
2.需要执行撤销和重做
3.多级撤销操作,如果系统需要实现多级撤销操作,如果用户的操作都是以Command对象的形式实现,系统可以简单的使用stack的方式来保存最近执行的命令,如果需要执行撤销操作系统之需要popup一个最精的对象后执行对应的撤销操作即可
4.原子事务行为,当原子行为失败时,需要回退到执行前的状态,可以借助Command对象保存状态,执行会滚操作,这里可以结合备忘录模式进行回滚操作
5.系统需要执行一系列命令时,每个Command对象给出对应估计时间那么系统可以简单的评估执行状态并给出合适的进度显示
6.导航。假如使用多个导航来完成一个动作。那么可以使用一个Command对象来封装整个导航过程,command对象会在第一个页面被创建时创建,每个页面接受的参数都设知道这个对象中。在最后一个页面结束时触发Command的执行动作来执行。通过这种方法Command对象不包含任何和用户界面有关的代码,可以实现用户界面和具体逻辑的分离
7.线程池, 通常一个典型的线程池实现类可能有一个名为addTask()的public方法,用来添加一项工作任务到任务 队列中。该任务队列中的所有任务可以用command对象来封装,通常这些command对象会实现一个通用的 接口比如java.lang.Runnable。 
8. 宏纪录, 可以用command对象来封装用户的一个操作,这样系统可以简单通过队列保存一系列的command对象的状 态就可以记录用户的连续操作。这样通过执行队列中的command对象,就可以完成"Play back"操作了
9.Networking, 通过网络发送command命令到其他机器上运行。 
10.并发处理, 当一个调用共享某个资源并被多个线程并发处理时。

7.code
抽象命令角色
//抽象命令
//定义所有需要执行的命令即行为
public abstract class Command {

    public abstract String execute();
}

抽象接受者
//抽象接收者
public interface Receiver {

    public String action();
}
具体命令角色
public class ConcreteCommand extends Command {

    private Receiver receiver;


    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

    @Override
    public String execute() {
        return receiver.action();
    }
}

具体接收角色
public class ConcreteReceiver implements Receiver {

    @Override
    public String action() {
        return "需要经数据插入数据库中";
    }
}

调用者角色
public class Invoker {

    private Command command;

    public void setCommand(Command command) {
        this.command = command;
    }

    public String exce() {
        return this.command.execute();
    }
}

客户端
public class Client {

    public static void main(String[] args) {

        Receiver receiver = new ConcreteReceiver();
        Command command = new ConcreteCommand(receiver);

        Invoker invoker = new Invoker();
        invoker.setCommand(command);
        System.out.println(invoker.exce());
    }
}
客户端存在如下问题:客户端依赖于接受者角色
code做如下修改
抽象命令角色
public abstract class Command {

    protected Receiver receiver;

    public Command(Receiver receiver) {
        this.receiver = receiver;
    }

    public abstract String execute();
}

具体命令角色
public class ConcreteCommand extends Command {

    public ConcreteCommand() {
        super(new ConcreteReceiver());
    }
    //设置新的接受者
    public ConcreteCommand(Receiver receiver) {
        super(receiver);
    }

    @Override
    public String execute() {
        return super.receiver.action();
    }
}
客户端
public class Client {

    public static void main(String[] args) {

        Command command1 = new ConcreteCommand();
        Invoker invoker1 = new Invoker();
        invoker1.setCommand(command1);
        System.out.println(invoker1.exce());
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值