命令模式:将命令封装成对象(下面示例中的Command对象),实现命令请求和命令执行者的解耦!

应用场景:1、出现一组命令的时候。2、需要实现undo操作的时候。3、命令请求与执行可能不是同步的是,需要实现异步处理;4、命令需要事务控制的时候

角色:

receiver执行命令的具体对象,命令的实际执行者!

ICommand 命令的抽象接口,将一组命令进行抽象;一般包含一个执行方法,一个undo方法;

Command 继承于ICommand,并实现命令的调用;

Invoker 命令调度者,

下面看具体实现:

设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

/**
 * @description 命令对象的抽象类
 * @author panteng
 * @date 17-2-21.
 */
public interface ICommand {
    void excute();

    void undo();
}
ICommand

 

设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

/**
 * @description Receiver命令的具体执行者
 *              厨房,可以做各种食物
 * @author panteng
 * @date 17-2-21.
 */
public class KitchenReceiver {
    public void getPie(){
        System.out.println("做一张大饼... ...");
    }

    public void getNoodles(){
        System.out.println("做一碗面条... ...");
    }

    public void getDumplings(){
        System.out.println("做一碗面条... ...");
    }
}
KitchenReceiver

 

设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

/**
 * @description 命令对象
 * @author panteng
 * @date 17-2-21.
 */
public class NoodlesCommand implements ICommand {
    KitchenReceiver receiver;
    public NoodlesCommand(){
    }

    public NoodlesCommand(KitchenReceiver r){
        this.receiver = r;
    }

    public void excute(){
        receiver.getNoodles();
    }

    public void undo(){
        System.out.println("取消面条订单... ...");
    }

    public KitchenReceiver getReceiver(){
        return receiver;
    }
    public void setReceiver(KitchenReceiver receiver){
        this.receiver = receiver;
    }
}
NoodlesCommand
设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

/**
 * @description 命令对象
 * @author panteng
 * @date 17-2-21.
 */
public class PieCommand implements ICommand {
    KitchenReceiver receiver;

    public PieCommand(){
    }

    public PieCommand(KitchenReceiver receiver){
        this.receiver = receiver;
    }
    public void excute(){
        receiver.getPie();
    }

    public void undo(){
        System.out.println("取消大饼订单... ...");
    }

    public KitchenReceiver getReceiver(){
        return receiver;
    }
    public void setReceiver(KitchenReceiver receiver){
        this.receiver = receiver;
    }
}
PieCommand
设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

/**
 * @description 命令对象
 * @author panteng
 * @date 17-2-21.
 */
public class DumplingsCommand implements ICommand {
    KitchenReceiver receiver;

    public DumplingsCommand(){
    }

    public DumplingsCommand(KitchenReceiver r){
        this.receiver = r;
    }
    public void excute(){
        receiver.getDumplings();
    }

    public void undo(){
        System.out.println("取消水饺订单... ...");
    }

    public KitchenReceiver getReceiver(){
        return receiver;
    }
    public void setReceiver(KitchenReceiver receiver){
        this.receiver = receiver;
    }
}
DumplingsCommand

 

设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

import java.util.ArrayList;
import java.util.List;

/**
 * @description
 * @author panteng
 * @date 17-2-21.
 */
public class WaiterInvoker {
    List<ICommand> commands = new ArrayList<ICommand>();

    public void order(){
        while (commands.size() > 0) {
            commands.get(0).excute();
            synchronized (WaiterInvoker.class) {
                commands.remove(0);
            }
        }
    }

    public void cancelOrder(ICommand iCommand){
        if (commands.contains(iCommand)) {//还未执行,直接移除
            commands.remove(iCommand);
        } else {//已经执行
            iCommand.undo();
        }
    }

    public ICommand addCommand(ICommand iCommand){
        synchronized (WaiterInvoker.class) {
            commands.add(iCommand);
            return iCommand;
        }
    }
}
WaiterInvoker

 

设计模式——命令模式_java设计模式——命令模式_java_02
/*
 * Copyright (c) 2017. Xiaomi.Co.Ltd All rights reserved
 */

package com.pt.command;

import org.junit.Test;

/**
 * @description
 * @author panteng
 * @date 17-2-21.
 */
public class CommandTest {
    @Test
    public void commandTest(){
        KitchenReceiver receiver = new KitchenReceiver();//厨房
        ICommand getNoodles = new NoodlesCommand(receiver);
        ICommand getDumplings = new DumplingsCommand(receiver);
        ICommand getPie = new PieCommand(receiver);

        WaiterInvoker waiter = new WaiterInvoker();
        waiter.addCommand(getNoodles);
        waiter.addCommand(getDumplings);

        waiter.order();
        waiter.addCommand(getPie);
        waiter.order();
        waiter.cancelOrder(getPie);
    }
}
CommandTest