介绍java
命令模式是一种行为型设计模式。在命令模式中,全部的请求都会被包装成为一个对象。设计模式
参考了一下其余关于命令模式的文章,其中有谈到说是能够用不一样的请求对客户进行参数化。对这句话的理解是,由于将请求封装成为对象,因此客户的全部操做,其实就是多个命令类的对象而已,即参数化了。
命令模式的最大的特色就是将请求的调用者与请求的最终执行者进行了解耦。调用者须要关心的仅仅是请求对象是否被执行了,对于请求对象是如何执行的,对什么进行操做的,通通不须要关心。ide
原理:命令模式中,通常有以下几个角色:ui
适用场景:涉及到“命令”、“操做”或者“控制”的场景,通常都是命令模式的适用场景。this
命令接口:spa
/** * @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("取消甜点"); } }
定义具体命令:code
/** * @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()); } } }
顾客购买:blog
/** * @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()); } } }
命令模式的核心思想就是将命令或者请求封装成对象,分离请求调用者和请求最终执行者。
优势:将请求调用者和执行者解耦,适用于底层接口封装,能够经过只增长类就能够实现接口扩展,不须要修改原来的代码。
缺点:若是存在较多的命令或者请求,须要较多的命令类。