命令模式

日常工作中,我们会经常需要向某些对象发送请求,但是并不知道请求的处理者是谁,我们只需要将请求扔给指定的接收者皆可,这个“中介”则会将请求分给对应的请求处理者。这种行为就是一种命令模式。
其实在生活中,我们身边就有很多的命令模式的例子。设想,你去吃饭的时候,点菜、催单、结账,并不是去直接找厨师或者收银员吧。而是中间存在一个“中介”---服务员,你只需要给服务员发出点菜、催单或结账的命令,服务员就会将你的命令传给特定的处理人---厨师或者收银员。
通过上述描述可以看到,命名模式中存在以下几种角色:

  • Command:抽象命令类。因为我们的命令并不是一个,而是多个,可以实现同一个抽象命令类
  • ConcreteCommand:具体命令类,例如:点菜、催单这就是具体的命令
  • Invoker:调用者,服务员就是具体命令的调用者
  • Receiver:命令接收者,厨师、收银员就是不同命令的接收者
  • Client:客户端,顾客就是客户端,给Invoker下达命令。

下面我们用代码实现一下之前讲解的示例:
首先:我们定义抽象的命令类 和 具体命令类(点菜、催单、结账3种命令)

public interface ICommand {
    // 具体的命令去实现执行内容
    void executor(String param);
}

// 点菜命令---交给厨师接收者
public class OrderCommand implements ICommand {
    @Override
    public void executor(String param) {
        // 点菜命令最终是交由厨师处理
        new CookerReceiver().order(param);
    }
}

// 催单命令---交给厨师接收者
public class UrgeCommand implements ICommand {
    @Override
    public void executor(String param) {
        // 催单命令最终是交由厨师处理
        new CookerReceiver().urge(param);
    }
}

// 结账命令---交给收银员接收者
public class CheckoutCommand implements ICommand {
    @Override
    public void executor(String param) {
        // 结账命令最终交给收银员
        new CheckerReceiver().checker(param);
    }
}

接下来,我们定义命令最终的接收者(厨师和收银员)

public class CookerReceiver {
    // 厨师接到下单命令的处理动作
    public void order(String param) {
        System.out.println(String.format("有客人点菜:%s,马上做", param));
    }

    // 厨师接到催单命令的处理动作
    public void urge(String param) {
        System.out.println(String.format("有客人催单:%s,快点做,否则没工资了", param));
    }
}

public class CheckerReceiver {
    // 收银员接到结账命令的处理动作
    public void checker(String param) {
        System.out.println(String.format("您点的菜是:%s,一共消费1888", param));
    }
}

然后,我们就可以组装命令的调用者---服务员了。服务员需要接收所有的命令。

public class Waiter {
    private ICommand orderCommand;
    private ICommand urgeCommand;
    private ICommand checkoutCommand;

    public Waiter(ICommand orderCommand, ICommand urgeCommand, ICommand checkoutCommand) {
        this.orderCommand = orderCommand;
        this.urgeCommand = urgeCommand;
        this.checkoutCommand = checkoutCommand;
    }

    public void order(String param) {
        orderCommand.executor(param);
    }

    public void urge(String param) {
        urgeCommand.executor(param);
    }

    public void checker(String param) {
        checkoutCommand.executor(param);
    }
}

最后,顾客就可以进行点菜、催单等操作了

public class Client {
    public static void main(String[] args) {
        // 创建命令对象
        ICommand orderCmd = new OrderCommand();
        ICommand urgeCmd = new UrgeCommand();
        ICommand checkoutCmd = new CheckoutCommand();

        // 创建命令传输对象---服务员
        Waiter waiter = new Waiter(orderCmd, urgeCmd, checkoutCmd);

        // 下单
        waiter.order("锅包肉");

        // 等了半天没来,催单
        waiter.urge("锅包肉");

        // 吃完了结账
        waiter.checker("锅包肉");
    }
}

通过上面的代码,我们发现完全把命令发出者(顾客)和命令处理者(厨师、收银员)完全解耦了。下面总结一下命令模式的优缺点:
优点:

  1. 命令发出和和命令处理者解耦,降低耦合
  2. 扩展性比较强,加入新的命令比较容易

缺点:

  1. 当命令比较多的时候,需要有大量的具体命令类
全部评论

相关推荐

点赞 收藏 评论
分享
牛客网
牛客企业服务