美文网首页
命令模式一

命令模式一

作者: 三流之路 | 来源:发表于2022-10-02 09:11 被阅读0次

    示例场景

    // 接收者
    public interface SonReceiver {
        public void pay(int money); // 交保护费
        public void bite(boolean b); // 咬人
        public void build(boolean b); // 军事基地建设
    }
    
    public class GuiZi implements SonReceiver {
        public void pay(int money) {
            System.out.println("上交保护费 " + money);
        }
        
        public void bite(boolean b) {
            if (b) {
                System.out.println("朝向东方某国竖中指,放狠话");
            } else {
                System.out.println("朝向东方某国,握手,我们是好朋友");
            }
        }
    
        public void build() {
            System.out.println("基地建设要不要放缓");
        }
    }
    
    public class BangZi implements SonReceiver {
        public void pay(int money) {
            System.out.println("上交保护费 " + money);
        }
        
        public void bite(boolean b) {
            if (b) {
                System.out.println("朝向东方某国,汪,汪汪");
            } else {
                System.out.println("朝向东方某国,喵,喵喵");
            }
        }
        public void build(boolean b) {
            System.out.println("基地建设要不要放缓 " + b);
        }
    }
    
    public class FatherDengTa {
        // 需要鞭策儿子了
        public void shouGuiZiBHF() {
            GuiZi gz = new GuiZi();
            gz.pay(5); 
            gz.bite(false); 
            gz.build(false);
        }
    
        public void shouBangZiBHF() {
            BangZi bz = new BangZi();
            bz.pay(1);
            bz.bite(true);
            bz.build(true);
        }
    }
    

    在例子中,爸爸亲自下场,和儿子要钱,爸爸只想要钱这么一个结果。

    但是儿子一看要的有点多,就和爸爸商量你这有点狠啊,那我是不是得缓和一下和东方某国的关系,这样能多赚点钱,爸爸一听说也行,儿子又说,要缓和关系,那咱军事基地就得缓一缓,不能刺激人家,爸爸一听毛了,那不行,算了,那钱少收点,儿子说那成,我继续咬东方某国。

    命令模式1.png

    这样一件一件事来谈,会很繁琐,爸爸很忙,哪里有时间管这么多事。

    中介者模式改造

    所以想着也抽出一个中介,通过中介去做。和中介者模式感觉有那么一点像,但中介者是两两有交互,形成一个网状结构,是类间横向有关系,所以抽出一个中介者,变成星形状。这里像是类内点纵向关系,是一个方法就引起其它方法变化。

    中介者模式.png

    爸爸不想管了,爸爸说我不管这么多了,我就给你一个命令:交钱,你自己掂量。先类似中介的方法改造。

    // 就不写抽象了
    public class Mediator {
        private GuiZi gz = new GuiZi();
        private BangZi bz = new BangZi();
        
        public void execute(String str,Object...objects){ 
            if (str.equals("guiZi.pay")) {
                gz.pay((int)objects[0]); // 假设交得太多了
                gz.bite(false); 
                gz.build(false);
            } else if (str.equals("bangZi.pay")) {
                bz.pay((int)objects[0]); // 交得不是很多
                bz.bite(true);
                bz.build(true);
            }
        }
    }
    
    public class FatherDengTa() {
        private Mediator mediator;
        public FatherDengTa(Mediator _mediator){
            this.mediator = mediator;
        }  
        
        public void shouGuiZiBHF() {
            mediator.execute("guiZi.pay", 5)
        }
    
        public void shouBangZiBHF() {
            mediator.execute("bangZi.pay", 1)
        }
    }
    
    public class GuiZi {
        private Mediator mediator;
        public GuiZi(Mediator _mediator){
            this.mediator = mediator;
        }  
    
        public void pay(int money) {
            System.out.println("上交保护费 " + money);
        }
        
        public void bite(boolean b) {
            if (b) {
                System.out.println("朝向东方某国竖中指,放狠话");
            } else {
                System.out.println("朝向东方某国,握手,我们是好朋友");
            }
        }
    
        public void build() {
            System.out.println("基地建设要不要放缓");
        }
    }
    

    失败了,因为 GuiZi 作为底层的,不需要和其它交流,中介者给它也用不着。

    命令模式改造

    将命令封装成 Command,Command 本身就能明确哪个接收者该做什么事情。

    public abstract class Command {  
        protected int money;
        public Command(int money) {
            this.money = money;
        }
        //接收者定义好
        protected GuiZi gz = new GuiZi(); 
        protected BangZi bz = new BangZi();
        // 只有一个执行方法
        public abstract void execute();
    }
    
    // 一个具体的命令本身,既能表明接收者是谁,又能表明需要做什么
    public GuiZiPayCommand extends Command {
        public GuiZiPayCommand(int money) {
            super(money);
        }
        public void execute() {
            gz.pay(money);
            gz.bite(false);
            gz.build(false);
        }
    }
    
    // 类似中介,负责接收高层的命令,负责执行命令,命令一旦执行,就到了底层的接收者了
    public class Invoker {
        private Command cmd;
        public void setCommand(Command command) {
            cmd = command;
        }
        public void action() {
            cmd.execute();
        }
    }
    
    public class FatherDengTa() {
        private Invoker invoker = new Invoker(); // 中介
        
        public void shouGuiZiBHF() {
            Command cmd = new GuiZiPayCommand(5);
            invoker.setCommand(cmd);
            invoker.action();
        }
    }
    
    命令模式2.png

    特点

    1. 解耦,爸爸只需要把命令给执行者 Invoker,Invoker 只需要执行 Command,具体的逻辑都封装到 Command 内部去了。
    2. 方便扩展,多一件事情,只需要创建一个命令,修改命令对象的引用,其它都不需要改
    3. 当交互对象多了后,中介者会越大越复杂,这里也是,如果要做的事情多了后,每个都需要定义一个 Command,会越来越多,甚至感觉太细碎。

    相关文章

      网友评论

          本文标题:命令模式一

          本文链接:https://www.haomeiwen.com/subject/jgyjartx.html