命令者模式是一个对象, 它封装了调用另一个方法的所有细节, 命令者模式使用该对象, 可以编写出根据运行期条件, 顺序调用方法的一般化代码。
成员:
命令接收者
执行实际任务
命令者
封装了所有调用命令执行者的信息
发起者
控制一个或多个命令的顺序和执行
客户端
创建具体的命令者实例
举个例子:
领导要加一个功能就是命令,那么就要有产品出需求,设计出设计,程序员编码。领导不会产品部、设计部、程序员一个一个部门找来讲,只要发一个添加功能的命令就可以了。那么就需要一个接头人,这个接头人就是 发起者。
代码示例:
public class CommandTest {
/**
* 命令接收者接口
* 用来组织所有的命令
*/
interface ReceiveCommand {
//这一个方法就是一个命令
void add();
void update();
void delete();
}
/**
* 命令接收者
* 产品部门
*/
static class Product implements ReceiveCommand {
@Override
public void add() {
System.out.println("Product add");
}
@Override
public void update() {
System.out.println("Product update");
}
@Override
public void delete() {
System.out.println("Product delete");
}
}
/**
* 命令接收者
* 设计部门
*/
static class Design implements ReceiveCommand {
@Override
public void add() {
System.out.println("design add");
}
@Override
public void update() {
System.out.println("design update");
}
@Override
public void delete() {
System.out.println("design delete");
}
}
/**
* 命令接收者
* 程序员
*/
static class Coder implements ReceiveCommand {
@Override
public void add() {
System.out.println("Coder add");
}
@Override
public void update() {
System.out.println("Coder update");
}
@Override
public void delete() {
System.out.println("Coder delete");
}
}
/**
* 命令者
* 封装所有的命令
* 每一个命令都要有一个实现,并且都是 命令者的子类
*/
static abstract class Command{
ReceiveCommand product = new Product();
ReceiveCommand design = new Design();
ReceiveCommand coder = new Coder();
public Command(ReceiveCommand product, ReceiveCommand design, ReceiveCommand coder) {
this.product = product;
this.design = design;
this.coder = coder;
}
public Command() {}
//使用这一个方法封装所有的命令
public abstract void execute();
}
/**
* 每一个命令对应一个类,这个类要实现 Command 接口
* 下面实现 add , update , delete 命令的实现
*
* add 命令
*/
static class AddCommand extends Command {
@Override
public void execute() {
super.product.add();
super.design.add();
super.coder.add();
}
}
/**
* update 命令
*/
class UpdateCommand extends Command {
@Override
public void execute() {
super.product.update();
super.design.update();
super.coder.update();
}
}
/**
* delete 命令
*/
class DeleteCommand extends Command {
@Override
public void execute() {
super.product.delete();
super.design.delete();
super.coder.delete();
}
}
/**
* 发起者
* 控制一个或多个命令的顺序和执行
*/
static class Invoker {
//命令
private Command command;
public Invoker(Command command) {
this.command = command;
}
//执行命令
public void action(){
command.execute();
}
}
public static void main(String[] args) {
AddCommand command = new AddCommand();
Invoker invoker = new Invoker(command);
invoker.action();
}
}
说明:
1、interface ReceiveCommand 命令接收者接口,统一了所有命令。所有的命令者都要继承此接口。其中每一个方法,都是一个命令。
2、Product Design Coder 分别是产品、设计、程序员是对应的命令接收者的实现
3、abstract class Command 就命令发起者,所有的命令者要继承此类,有三个ReceiveCommand 属性,分别对应产品命令接收者,设计命令接收者,程序员命令接收者,抽象方法execute() 留给子类实现。
4、AddCommand、UpdateCommand、DeleteCommand 对应接口ReceiveCommand 中的每一个命令,并且extends Command。
5、Invoker 发起者,对外提供统一的方法action()执行命令
6、示例中main 方法测试的是一个AddCommand,直接修改成UpdateCommand 就可以发起修改需求的命令,领导并不知道内部是怎么动作的。
jdk8 实现
public class Test2 {
/**
* 命令接收者 执行实际任务
*/
static class ReceiveCommand{
public static void productAdd() {
System.out.println("Product add");
}
public static void productUpdate() {
System.out.println("Product update");
}
public static void productDelete() {
System.out.println("Product delete");
}
public static void designAdd() {
System.out.println("design add");
}
public static void designUpdate() {
System.out.println("design update");
}
public static void designDelete() {
System.out.println("design delete");
}
public static void coderAdd() {
System.out.println("coder add");
}
public static void coderUpdate() {
System.out.println("coder update");
}
public static void coderDelete() {
System.out.println("coder delete");
}
}
/**
* 命令者:
* 用一个接口封装所有的命令
*/
interface Command{
//使用这一个方法封装所有的命令
void execute();
}
/**
* 命令发起者
* 控制一个或多个命令的顺序和执行
*/
static class Invoker {
//命令集合
private List<Command> commands;
public Invoker() {
commands = new ArrayList<>();
}
public void addCommand(Command command) {
commands.add(command);
}
//执行命令
public void action(){
commands.forEach(Command::execute);
}
}
public static void main(String[] args) {
//调用命令
Invoker invoker = new Invoker();
invoker.addCommand(ReceiveCommand::productAdd);
invoker.addCommand(ReceiveCommand::designAdd);
invoker.addCommand(ReceiveCommand::coderAdd);
invoker.action();
}
}
说明:
1、ReceiveCommand 定义了所有的命令(每一个方法就是一个命令)
2、interface Command 是命令者,主要在使用“函数接口”的特性
3、Invoker 命令发起者,使用一个集合来保存命令,action() 方法对集合中的命令依次调用
4、和上面的相比,没有了命令接收者的类,和每一个命令的实现就是一个方法
枚举实现
把所有的命令组成一个枚举,此枚举要实现一个命令接口,用来统一命令处理方法。在调用时和jdk8一样。
public class Test3 {
interface Command {
void execute();
}
/**
* 命令接收者 执行实际任务
*/
enum ReceiveCommand implements Command {
ProductAdd {
public void execute() {
System.out.println("Product add");
}
},
ProductUpdate {
public void execute() {
System.out.println("Product update");
}
},
ProductDelete {
public void execute() {
System.out.println("Product delete");
}
},
DesignAdd {
public void execute() {
System.out.println("design add");
}
},
DesignUpdate {
public void execute() {
System.out.println("design update");
}
},
DesignDelete {
public void execute() {
System.out.println("design delete");
}
},
CoderAdd {
public void execute() {
System.out.println("coder add");
}
},
CodeUpdate {
public void execute() {
System.out.println("coder update");
}
},
CoderDelete {
public void execute() {
System.out.println("coder delete");
}
}
}
public static void main(String[] args) {
EnumSet<ReceiveCommand> command = EnumSet.noneOf(ReceiveCommand.class);
command.add(ReceiveCommand.ProductAdd);
command.add(ReceiveCommand.DesignAdd);
command.add(ReceiveCommand.CoderAdd);
command.stream().forEach(c-> c.execute());
}
}