介绍
命令模式是一种行为型设计模式。在命令模式中,所有的请求都会被包装成为一个对象。
参考了一下其他关于命令模式的文章,其中有谈到说是可以用不同的请求对客户进行参数化。对这句话的理解是,因为将请求封装成为对象,所以客户的所有操作,其实就是多个命令类的对象而已,即参数化了。
命令模式的最大的特点就是将请求的调用者与请求的最终执行者进行了解耦。调用者需要关心的仅仅是请求对象是否被执行了,对于请求对象是如何执行的,对什么进行操作的,统统不需要关心。
原理:命令模式中,一般有如下几个角色:
适用场景:涉及到“命令”、“操作”或者“控制”的场景,一般都是命令模式的适用场景。
命令接口:
/**
* @program: test
* @description: 命令
* @author: xingcheng
* @create: 2018-09-02 15:16
**/
public interface Command {
/**
* 执行命令
*/
void execute();
}
定义receiver:
/**
* @program: test
* @description: 水果
* @author: xingcheng
* @create: 2018-09-02 15:18
**/
public class Fruit {
/**
* 点一份水果
*/
void orderFruit(){
System.out.println("来一份水果");
}
/**
* 取消水果
*/
void cancelFruit(){
System.out.println("取消水果");
}
}
/**
* @program: test
* @description: 牛奶
* @author: xingcheng
* @create: 2018-09-02 15:22
**/
public class Milk {
/**
* 点一份牛奶
*/
void orderMilk(){
System.out.println("来一份牛奶");
}
/**
* 取消牛奶
*/
void cancelMilk(){
System.out.println("取消牛奶");
}
}
/**
* @program: test
* @description: 甜点
* @author: xingcheng
* @create: 2018-09-02 15:17
**/
public class Mousse {
/**
* 点一份甜点
*/
void orderMousse(){
System.out.println("来一份甜点");
}
/**
* 取消甜点
*/
void cancelMousse(){
System.out.println("取消甜点");
}
}
定义具体命令:
/**
* @program: test
* @description: 点一份水果
* @author: xingcheng
* @create: 2018-09-02 15:29
**/
public class OrderFruit implements Command{
private Fruit fruit;
public OrderFruit(Fruit fruit) {
this.fruit = fruit;
}
/**
* 执行命令
*/
@Override
public void execute() {
fruit.orderFruit();
}
}
/**
* @program: test
* @description: 点一份牛奶
* @author: xingcheng
* @create: 2018-09-02 15:25
**/
public class OrderMilk implements Command{
private Milk milk;
public OrderMilk(Milk milk) {
this.milk = milk;
}
/**
* 执行命令
*/
@Override
public void execute() {
milk.orderMilk();
}
}
/**
* @program: test
* @description: 点一份甜点
* @author: xingcheng
* @create: 2018-09-02 15:31
**/
public class OrderMousse implements Command{
private Mousse mousse;
public OrderMousse(Mousse mousse) {
this.mousse = mousse;
}
/**
* 执行命令
*/
@Override
public void execute() {
mousse.orderMousse();
}
}
/**
* @program: test
* @description: 取消水果
* @author: xingcheng
* @create: 2018-09-02 15:30
**/
public class CancelFruit implements Command {
private Fruit fruit;
public CancelFruit(Fruit fruit) {
this.fruit = fruit;
}
/**
* 执行命令
*/
@Override
public void execute() {
fruit.cancelFruit();
}
}
/**
* @program: test
* @description: 取消牛奶
* @author: xingcheng
* @create: 2018-09-02 15:27
**/
public class CancelMilk implements Command{
private Milk milk;
public CancelMilk(Milk milk) {
this.milk = milk;
}
/**
* 执行命令
*/
@Override
public void execute() {
milk.cancelMilk();
}
}
/**
* @program: test
* @description: 取消甜点
* @author: xingcheng
* @create: 2018-09-02 15:32
**/
public class CancelMousse implements Command {
private Mousse mousse;
public CancelMousse(Mousse mousse) {
this.mousse = mousse;
}
/**
* 执行命令
*/
@Override
public void execute() {
mousse.cancelMousse();
}
}
定义菜单(invoker)
/**
* @program: test
* @description: 菜单
* @author: xingcheng
* @create: 2018-09-02 15:36
**/
public class Menu {
private List<Command> commands;
public Menu() {
this.commands = new ArrayList<>();
}
/**
* 记录顾客需要什么
*/
public void writeMenu(Command command){
commands.add(command);
}
/**
* 将菜单交给厨师
*/
public void giveCooker(){
if (commands != null && commands.size() > 0){
commands.forEach(command -> command.execute());
}
}
}
顾客购买:
/**
* @program: test
* @description: 顾客
* @author: xingcheng
* @create: 2018-09-02 15:34
**/
public class Consumer {
public static void main(String[] args) {
Fruit fruit = new Fruit();
Milk milk = new Milk();
Mousse mousse = new Mousse();
// 店小二记录菜单
System.out.println("店小二记录菜单----------------------------------------------");
Menu menu = new Menu();
menu.writeMenu(new OrderFruit(fruit));
menu.writeMenu(new OrderMilk(milk));
menu.writeMenu(new OrderMousse(mousse));
// 店小二将菜单交给厨师
menu.giveCooker();
// 顾客取消菜单--太贵了不吃了╭(╯^╰)╮
System.out.println("顾客取消菜单--太贵了不吃了╭(╯^╰)╮----------------------------");
Menu menuCancel = new Menu();
menuCancel.writeMenu(new CancelFruit(fruit));
menuCancel.writeMenu(new CancelMilk(milk));
menuCancel.writeMenu(new CancelMousse(mousse));
menuCancel.giveCooker();
System.out.println("宏命令----------------------------");
List<Command> commands = new ArrayList<>();
commands.add(new CancelFruit(fruit));
commands.add(new CancelMilk(milk));
commands.add(new CancelMousse(mousse));
MutilCommand mutilCommand = new MutilCommand(commands);
mutilCommand.giveCooker();
}
}
结果:
命令模式中有一种扩展,叫做宏命令,能同时进行一组命令的执行。比如遥控器只存在两个按键,一个控制所有电器的开启,一个控制所有电器的关闭。那么我们不需要改动已有的代码,只要扩展一个组合命令类,其中包含多个命令即可。
/**
* @program: test
* @description: 宏命令(组合命令)
* @author: xingcheng
* @create: 2018-09-02 15:59
**/
public class MutilCommand {
private List<Command> commands;
public MutilCommand(List<Command> commands) {
this.commands = commands;
}
/**
* 记录顾客需要什么
*/
public void writeMenu(Command command){
commands.add(command);
}
/**
* 将菜单交给厨师
*/
public void giveCooker(){
if (commands != null && commands.size() > 0){
commands.forEach(command -> command.execute());
}
}
}
命令模式的核心思想就是将命令或者请求封装成对象,分离请求调用者和请求最终执行者。
优点:将请求调用者和执行者解耦,适用于底层接口封装,可以通过只增加类就可以实现接口扩展,不需要修改原来的代码。
缺点:如果存在较多的命令或者请求,需要较多的命令类。
(adsbygoogle = window.adsbygoogle || []).push({});