前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >命令模式一

命令模式一

作者头像
三流编程
发布2022-10-04 08:36:03
1530
发布2022-10-04 08:36:03
举报

示例场景

代码语言:javascript
复制
// 接收者
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

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

代码语言:javascript
复制
// 就不写抽象了
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 本身就能明确哪个接收者该做什么事情。

代码语言:javascript
复制
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,会越来越多,甚至感觉太细碎。
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-10-02,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 示例场景
  • 中介者模式改造
  • 命令模式改造
  • 特点
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档