设计模式-命令模式

本文深入解析命令模式的设计理念,通过具体实例展示如何将请求封装为对象,实现客户端参数化、请求队列化及操作可撤销性,有效降低系统耦合度,提升扩展性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

定义

Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)

我们可以引入一个场景,假如一个公司在刚成立规模还小,老板还没钱给自己配秘书,老板需要和三个组(技术部、策划部、行政部)都要沟通。
代码如下:
抽象出公共方法

/**
 * @author shuliangzhao
 * @Title: Group
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:37
 */
public abstract class Group {

    public abstract void add();

    public abstract void del();

    public abstract void change();

    public abstract void plan();

}

策划部 PlanDepartGroup

/**
 * @author shuliangzhao
 * @Title: PlanDepartGroup
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:41
 */
public class PlanDepartGroup extends Group {
    @Override
    public void add() {
        System.out.println("策划部新增策划方案");
    }

    @Override
    public void del() {
        System.out.println("策划部删除策划方案");
    }

    @Override
    public void change() {
        System.out.println("策划部修改策划方案");
    }

    @Override
    public void plan() {
        System.out.println("策划部变更策划方案");
    }
}

技术部 TechDepartGroup

/**
 * @author shuliangzhao
 * @Title: TechDepartGroup
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:39
 */
public class TechDepartGroup extends Group {
    @Override
    public void add() {
        System.out.println("技术部增加需求");
    }

    @Override
    public void del() {
        System.out.println("技术部删除需求");
    }

    @Override
    public void change() {
        System.out.println("技术部修改需求");
    }

    @Override
    public void plan() {
        System.out.println("技术部变更需求");
    }
}

行政部 AdminDepartGroup

/**
 * @author shuliangzhao
 * @Title: AdminDepartGroup
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:42
 */
public class AdminDepartGroup extends Group {
    @Override
    public void add() {
        System.out.println("行政部新增考勤规范");
    }

    @Override
    public void del() {
        System.out.println("行政部删除考勤规范");
    }

    @Override
    public void change() {
        System.out.println("行政部变更考勤规范");
    }

    @Override
    public void plan() {
        System.out.println("行政部执行新的考勤规范");
    }
}

场景类

/**
 * @author shuliangzhao
 * @Title: Client
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:45
 */
public class Client {

    public static void main(String[] args) {
        System.out.println("======老板给行政组下发任务==========");
        AdminDepartGroup adminDepartGroup = new AdminDepartGroup();
        adminDepartGroup.add();
        adminDepartGroup.change();
        adminDepartGroup.del();
    }
}

执行结果

 

image.png

然后老板又给技术部,策划部下发任务。这样每天周而复始在给不同部门下发任务,由此一来老板都没有时间规划公司的发展了,老板一看这样不行啊,必须要给自己找一个下手,来分担这样的工作。老板要的这个人,需要做的就是,我给你一个指令你去告诉大家要怎么要,不用我自己天天出面。

因此上面设计已经不符合,我们需要从新设计。
首先抽象一个Commond类,这个类只有一个execute方法。然后具体的命令继承这个Commond类。
Invoker实现类,setComand接收老板发给我们的命令,action方法是执行老板的命令。

因此我们需要增加几个类来完成我们现在的设计

命令类 Commond

/**
 * @author shuliangzhao
 * @Title: Commond
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 21:57
 */
public abstract class Commond {

    protected AdminDepartGroup adminDepartGroup = new AdminDepartGroup();

    protected PlanDepartGroup planDepartGroup = new PlanDepartGroup();

    protected TechDepartGroup techDepartGroup = new TechDepartGroup();

    //要告诉我做什么
    public abstract  void execute();
}

新增考勤规范命令


/**
 * @author shuliangzhao
 * @Title: AddAdminDepartGroup
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 22:00
 */
public class AddAdminDepartGroup extends Commond {
    @Override
    public void execute() {
        super.adminDepartGroup.add();
        super.adminDepartGroup.plan();
    }
}

负责命令的人Invoker

/**
 * @author shuliangzhao
 * @Title: Invoker
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 22:01
 */
public class Invoker {

    private Commond commond;

    public Invoker(Commond commond) {
        this.commond = commond;
    }

    public void action() {
        commond.execute();
    }
}

场景类


/**
 * @author shuliangzhao
 * @Title: Client
 * @ProjectName design-parent
 * @Description: TODO
 * @date 2019/6/4 22:02
 */
public class Client {

    public static void main(String[] args) {
        Invoker invoker = new Invoker(new AddAdminDepartGroup());
        invoker.action();
    }
}

执行结果

 

image.png

这更简单了,负责人只要接到老板的命令,就立刻执行。

命令模式的优点

1.类间解耦,调用者角色与接收者角色之间没有任何依赖关系。
2.可扩展性,Command的子类可以非常容易地扩展。

命令模式的缺点

代码写的比较多,有N个命令,就需要写N个类。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

境里婆娑

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值