命令模式

一、定义

将一个请求封装成一个对象,从而让用户使用不同的请求把客户端参数化;对请求排队或者记录请求日志,以及支持可撤销操作。

二、使用场景

需要对请求排队或者记录请求日志,以及支持可撤销操作时,可使用命令模式。

三、UML类图

命令模式

Receiver:命令接受者,执行具体命令。
Command:抽象命令,定义所有具体命令类的抽象接口。
ConcreteCommand:具体命令,实现抽象命令类中定义的接口。
Invoker:请求者,调用命令对象执行具体的请求。
Client:客户端。

四、实现

//命令处理者
public class Receiver {
    public void action() {
        System.out.println("执行具体操作");
    }
}

//命令接口
public interface Command {
    void execute();
}

//具体命令
public class ConcreteCommand implements Command {
    private Receiver receiver;
    
    public ConcreteCommand(Receiver receiver) {
        this.receiver = receiver;
    }

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

//命令请求者
public class Invoker {
    private Command command;
  
    public Invoker(Command command) {
        this.command = command;
    }

    public void action() {
        command.execute();
    }
}

//客户端
public class Client {
    public static void main(String[] args) {
        Receiver receiver = new Receiver();
        Command command = new ConcreteCommand(receiver);
        Invoker invoker = new Invoker(command);
        invoker.action();
    } 
}

五、应用

例子:烤肉串

//烤肉串者
public class Barbecuer {
    public void bakeMutton() {
        System.out.println("烤羊肉串");
    }

    public void bakeChickenWing() {
        System.out.println("烤鸡翅");
    }
}

//抽象命令
public abstract class Command {
    protected Barbecuer receiver;
    
    public Command(Barbecuer receiver) {
        this.receiver = receiver;
    }

    public abstract void executeCommand();
}

//烤羊肉串命令
public BakeMuttonCommand extends Command {
    public BakeMuttonCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void executeCommand() {
        receiver.bakeMutton();
    }
}

//烤鸡翅命令
public BakeChickenWingCommand extends Command {
    public BakeChickenWingCommand(Barbecuer receiver) {
        super(receiver);
    }

    @Override
    public void executeCommand() {
        receiver.bakeChickenWing();
    }
}

//服务员
public class Waiter {
    private List<Command> orders = new ArrayList<>();

    public void setOrder() {
        if(command.toString().equals("BakeChickenWingCommand")) {
            System.out.println("服务员:鸡翅没有了,请点别的烧烤。");
        } else {
            orders.add(command);
            System.out.println("增加订单:" + command.toString());
        }
    }

    public void cancelOrder(Command command) {
        orders.remove(command);
        System.out.println("取消订单:" + command.toString());
    }

    public void notify() {
        foreach(Command cmd : orders) {
            cmd.executeCommand();
        }
    }
}

//客户端
public class Client {
    public static void main(String[] args) {
        Barbecuer boy = new Barbecuer();
        Command bakeMuttonCommand1 = new BakeMuttonCommand(boy);
        Command bakeMuttonCommand2 = new BakeMuttonCommand(boy);
        Command bakeChickenWingCommand1 = new BakeChickenWingCommand(boy);
        Waiter girl = new Waiter();

        girl.setOrder(bakeMuttonCommand1);
        girl.setOrder(bakeMuttonCommand2);
        girl.setOrder(bakeChickenWingCommand1);
        
        girl.notify();
    }
}

六、总结

命令模式的应用其实可以用一句话来概述,就是将行为请求者与行为实现者解耦。通过引入一个中间者可以实现对请求排队或者记录请求日志,以及支持可撤销操作。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

推荐阅读更多精彩内容