命令模式

二嫂的烧烤摊

  大家好,我是小赵,现任藏剑山庄高级铸剑师,在山庄里任职的这段时间,和老王他们几个成了好朋友,经常一起吹牛逼打飞机。

  今天周末,晚上八点左右,我们商量着去老王他二嫂那蹭一顿烧烤吃,老王的二嫂在山楂街通汇桥上摆了个烧烤摊,据说生意还不错,比我们上班强多了。

 

  “老板娘,10串牛肉10串羊肉1斤小龙虾!羊肉不要辣!”

  “老板娘,1个鸡腿2个鸡翅2串羊肉5串金针菇,羊肉不要辣!”

  “老板娘,3串鸡胗5串香菇2串羊肉2串鸡肉,鸡肉不要辣,羊肉微辣!”

  “老板娘,10串羊肉2个鸡腿3个鸡翅,羊肉中辣,其他微辣!”

  ...............

  场面一度火爆,露天的小桌子都坐满了客人,点餐的点餐,催餐的催餐,老王二嫂一个人又负责点餐还负责烤菜,忙的天昏地暗。

 

  “老赵,来几段代码玩玩。” 老王边嗑瓜子边说,老王就是这样,对我一本正经写的程序不感冒,反倒喜欢即兴表演,把眼前看到的事情用代码的方式写下来很有兴趣。

 

  我想了想说:“那就写顾客点餐吧。”

 

类图:

我是老板娘:

public class Boss {
    public void orderMutton(){
        System.out.println("烤一份羊肉");
    }

    public void orderChicken(){
        System.out.println("烤一份鸡肉");
    }

    public void orderBeef(){
        System.out.println("烤一份牛肉");
    }
}

 

主函数:

    public static void main(String[] args) {
        User zhangsan = new User();
        zhangsan.orderBeef();
        zhangsan.orderChicken();
        zhangsan.orderMutton();
    }

 

输出:

烤一份牛肉
烤一份鸡肉
烤一份羊肉

 

  “好了,写完了,大家看看,有什么问题?”。

  “调用一个类的方法,这能看出个毛线?” 老王碎了一口瓜子皮。

  “小王!过来帮忙!” 还没等我发作,老王二嫂的声音就朝这边喊了过来,估计那边实在是忙不过来了。

  这不,老王嗑着瓜子屁颠屁颠的过去帮忙了。

 

老王的帮忙

  有了老王的帮忙,二嫂顿时轻松了许多,只管烤菜,点餐的任务就交给老王了。

 

  只见老王跑来跑去四处招呼,时不时的朝二嫂那边大喊:

  “002桌一份牛肉!”

  “005桌一份鸡肉!”

  “005桌一份羊肉!”

  “006桌一份羊肉!”

  ..........

  老王完全对接了顾客和二嫂,成为了业务请求者和业务实现者的中间人,而顾客只需要对老王发送命令。

 

我想着想着,画下了流程图:

 

  由于每一个菜品都是一个命令,所以命令应该是抽象出来,并且所有菜品的最终命令都是由老王传达给二嫂执行,所以命令都有一个通知执行操作。

那么我们的类图就可以这么画:

  类图画好后,程序也就呼之欲出了:

我就是老王,我是调用者:

public class Invoker {
    private Command command;

    //记录命令
    public void setCommand(Command command){
        this.command = command;
    }

    //将命令发送给二嫂执行
    public void action(){
        this.command.execute();
    }
}

 

命令抽象:

public abstract class Command {
    protected Receiver receiver = new Receiver();
    public abstract void execute();//执行命令
}

 

羊肉:

public class CommandMutton extends Command {
    @Override
    public void execute() {
        super.receiver.mutton();
    }
}

 

鸡肉:

public class CommandChicken extends Command {
    @Override
    public void execute() {
        super.receiver.chicken();
    }
}

 

牛肉:

public class CommandBeef extends Command {
    @Override
    public void execute() {
        super.receiver.beef();
    }
}

 

我是老板娘,是命令的接收者:

public class Receiver {
    
    public void mutton(){
        System.out.println("烤一份羊肉");
    }
    
    public void chicken(){
        System.out.println("烤一份鸡肉");
    }
    
    public void beef(){
        System.out.println("烤一份牛肉");
    }
}

 

客户端:

    public static void main(String[] args) {
        Invoker wang = new Invoker();
        Command mutton = new CommandMutton();
        wang.setCommand(mutton);
        wang.action();
    }

 

输出:

烤一份羊肉

 

最后的干杯

  老王忙完后我们摆了一桌胡吃海喝。

  老刘把我的程序拿出来吹嘘说牛的一逼,结果老王一看,崩了两个字:“扯淡!”。

 

  “我说老赵,你这写的啥玩意儿?点一份菜我就要通知一下二嫂?我嗓子还不喊哑了吗?”

  这一问,我就陷入了沉默。

 

短暂的思索后,我改了一下Invoker类:

public class Invoker {
    private List<Command> list = new ArrayList<>();

    //记录命令
    public void setCommand(Command command){
        this.list.add(command);
    }

    //撤销命令
    public void removeCommand(Command command){
        this.list.remove(command);
    }

    //将命令发送给二嫂执行
    public void action(){
        for(Command command : list){
            command.execute();
        }
    }
}

 

客户端:

    public static void main(String[] args) {
        Invoker wang = new Invoker();
        Command mutton = new CommandMutton();
        Command mutton2 = new CommandChicken();
        wang.setCommand(mutton);
        wang.setCommand(mutton2);
        wang.action();
    }

 

输出:

烤一份羊肉
烤一份鸡肉

 

老王一看,举起酒杯一饮而尽,赞叹道:“Perfect!”

 

posted @ 2019-05-07 10:46  不该相遇在秋天  阅读(852)  评论(6编辑  收藏  举报