行为型模式:命令模式

LieBrother原文:

行为型模式:命令模式

十一大行为型模式之三:命令模式。

简介

姓名 :命令模式

英文名 :Command Pattern

价值观 :军令如山

个人介绍

Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.

将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。

(来自《设计模式之禅》)

你要的故事

作为一个程序猿,我们每天都在经历着命令模式,技术经理把需求任务分配给工程师开发,有时因为第三方或者其他不可抗拒的因素导致需求停止开发。这种工作模式就是命令模式。好了,开始故事了。小明在 XX 科技公司做一个安静的程序猿,有一天技术经理给他分配了一个任务:新增黑名单,也就是在他们系统的某个模块里面可以手工对电话打黑名单标签的功能。小明接到任务后就立马开发,在开发了 2 天之后,因为战略原因,技术经理大明暂停了这个开发任务,接下来我们通过非命令模式和命令模式 2 种代码实现来体现这个过程。在这个场景中,为了简单,我们假定技术经理大明手下只有小明一个开发人员。

非命令模式

非命令模式也就是不使用命令模式的代码实现。代码中,我们出现了 Developer 开发人,开发同学是接受技术经理传达的任务,技术经理让他开发哪个需求就开发哪个需求,如果项目有问题需要中断,也需要技术经理评估后传达给开发同学,所以 Developer 有 2 个方法,分别是 develop() 开发需求和 suspend() 暂停需求。 Requirement 则为需求类,TechnicalManager1 则为技术经理类,他有一个方法 action(),通过这个方法来指定开发同学开发任务或者暂停任务。

public class NoCommandTest {

    public static void main(String[] args) {
        Developer xiaoMing = new Developer("小明");
        Requirement requirement = new Requirement("新增黑名单");
        TechnicalManager1 technicalManager2 = new TechnicalManager1("大明");
        technicalManager2.setDeveloper(xiaoMing);
        technicalManager2.action(requirement, "develop");
        System.out.println("开发了 2 天,需求变故,需要暂停。。。");
        technicalManager2.action(requirement, "suspend");
    }

}

/**
 * 开发人员
 */
class Developer {

    private String name;

    public Developer(String name) {
        this.name = name;
    }

    public void develop(Requirement requirement) {
        System.out.println(this.name + " 开始开发需求:" + requirement.getName());
    }

    public void suspend(Requirement requirement) {
        System.out.println(this.name + " 停止开发需求:" + requirement.getName());
    }

    public String getName() {
        return name;
    }

}

/**
 * 需求
 */
class Requirement {
    private String name;

    public Requirement(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

}

/**
 * 技术经理
 */
class TechnicalManager1 {

    private String name;

    private Developer developer;

    public TechnicalManager1(String name) {
        this.name = name;
    }

    public void setDeveloper(Developer developer) {
        this.developer = developer;
    }

    public void action(Requirement requirement, String type) {
        if ("develop".equals(type)) {
            this.developer.develop(requirement);
        } else if ("suspend".equals(type)) {
            this.developer.suspend(requirement);
        }
    }

}

打印结果:
小明 开始开发需求:新增黑名单
开发了 2 天,需求变故,需要暂停。。。
小明 停止开发需求:新增黑名单

通过代码,我们可以发现技术经理和开发同学是强依赖关系。如果技术经理下达了一个任务,要求小明写一下周报,这时候得怎么写?是不是小明需要一个写周报的方法,大明也需要新增一个处理事务类型?有没有更好的方法让技术经理不需要做任何改变?命令模式就来解决这个问题。

命令模式

在这个例子中,不管大明叫小明做什么事情,其实都是一样的,就是下达任务命令,让小明去执行命令。我们可以利用命令模式把下达任务这个抽象起来,当做父类,下达开发命令、下达暂停命令、下达写周报等等都是不同的子命令。代码如下。

public class CommandTest {

    public static void main(String[] args) {
        Developer xiaoMing = new Developer("小明");
        Command developCommand = new DevelopCommand(xiaoMing);
        Command suspendCommand = new SuspendCommand(xiaoMing);
        Requirement requirement = new Requirement("新增黑名单");
        TechnicalManager2 technicalManager = new TechnicalManager2("大明");
        technicalManager.setCommand(developCommand);
        technicalManager.action(requirement);
        System.out.println("开发了 2 天,需求变故,需要暂停。。。");
        technicalManager.setCommand(suspendCommand);
        technicalManager.action(requirement);

    }

}

/**
 * 命令
 */
abstract class Command {

    protected Developer developer;

    public Command(Developer developer) {
        this.developer = developer;
    }

    public abstract void execute(Requirement requirement);
}

/**
 * 开始开发
 */
class DevelopCommand extends Command {

    public DevelopCommand(Developer developer) {
        super(developer);
    }

    @Override
    public void execute(Requirement requirement) {
        this.developer.develop(requirement);
    }
}

/**
 * 开发中断
 */
class SuspendCommand extends Command {

    public SuspendCommand(Developer developer) {
        super(developer);
    }

    @Override
    public void execute(Requirement requirement) {
        this.developer.suspend(requirement);
    }
}

/**
 * 技术经理
 */
class TechnicalManager2 {

    private String name;
    private Command command;

    public TechnicalManager2(String name) {
        this.name = name;
    }

    public void action(Requirement requirement) {
        this.command.execute(requirement);
    }

    public void setCommand(Command command) {
        this.command = command;
    }
}

打印结果:
小明 开始开发需求:新增黑名单
开发了 2 天,需求变故,需要暂停。。。
小明 停止开发需求:新增黑名单

代码中用 Command 来抽象下达任务,而技术经理 TechnicalManager2 并没有和 Developer 有直接的关系,而是 TechnicalManager2 和 Command 建立的联系,Command 和 Developer 建立了联系。这样子把大明和小明的强依赖关系给剥离开,而新增一个下达写周报的任务也很简单,在 Developer 中新增一个处理写周报的方法,新增一个写周报的 Command 子类,就可以了,TechnicalManager2 如上面所愿不用修改。这就是完整的一个命令模式代码。

代码:

Command Pattern

总结

从文章中我们就可以看到,利用命令模式能够进行类的解耦,让调用者和接受者没有任何关系,也通过对行为的抽象,让新增其他行为变得清晰容易,也就是可扩展性大大增加

参考资料:《大话设计模式》、《设计模式之禅》

推荐阅读:

公众号之设计模式系列文章

希望文章对您有所帮助,设计模式系列会持续更新,感兴趣的同学可以关注公众号:LieBrother,第一时间获取文章推送阅读,也可以一起交流,交个朋友。

原文地址:https://www.cnblogs.com/liebrother/p/10420612.html

时间: 2024-11-08 20:24:39

行为型模式:命令模式的相关文章

java设计模式--行为型模式--命令模式

1 命令模式 2 概述 3 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤消的操作. 4 5 6 适用性 7 1.抽象出待执行的动作以参数化某对象. 8 9 2.在不同的时刻指定.排列和执行请求. 10 11 3.支持取消操作. 12 13 4.支持修改日志,这样当系统崩溃时,这些修改可以被重做一遍. 14 15 5.用构建在原语操作上的高层操作构造一个系统. 16 17 18 参与者 19 1.Command 20 声明执行操作的接口.

行为型模型 命令模式

行为型模型 命令模式 Command         Command命令的抽象类. ConcreteCommand         Command的具体实现类. Receiver         需要被调用的目标对象. Invorker         通过Invorker执行Command对象. 适用于:         是将一个请求封装为一个对象,从而使你可用不同的请求对客户端进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. /** * 行为型模型 命令模式 * Command模

Java设计模式(九)责任链模式 命令模式

(十七)责任链模式 责任链模式的目的是通过给予多个对象处理请求的机会,已解除请求发送者与接受者之间的耦合关系.面对对象的开发力求对象之前保持松散耦合,确保对象各自的责任最小化,这样的设计可以使得系统更加容易修改,同时降低产生缺陷的风险. public class ChainTest { public static void main(String[] args) { String pass1="123456"; String pass2="123456"; Stri

第16章 行为型模式—命令模式

1. 命令模式(Command Pattern)的定义 (1)定义 将一个请求封装为一个对象,从而使你可用不同的请求对客户进行参数化:对请求排队或记录请求日志,以及支持可撤销的操作. ①封装请求:抽象出需要执行的动作,封装成对象(有统一的接口). ②参数化:可以用不同的命令对象,去参数化配置客户的请求.(即,将命令对象作为参数去供Invoker调用). (2)命令模式的结构和说明 ①Command:定义命令的接口,声明执行的方法 ②ConcreteCommand:命令接口实现对象,是“虚”的实现

设计模式(行为型)之命令模式(Command Pattern)

PS一句:最终还是选择CSDN来整理发表这几年的知识点,该文章平行迁移到CSDN.因为CSDN也支持MarkDown语法了,牛逼啊! [工匠若水 http://blog.csdn.net/yanbober] 阅读前一篇<设计模式(行为型)之策略模式(Strategy Pattern)>http://blog.csdn.net/yanbober/article/details/45498567 概述 在软件开发中,我们经常需要向某些对象发送请求(调用其中的某个或某些方法),但是并不知道请求的接收

15 行为型模式-----命令模式

模式动机(Command Pattern):将请求封装为对象,从而可以用不同的请求对客户进行参数化:对请求进行排队或记录请求日志:设计可撤销的结构等,这些都是命令模式发挥作用的环境.核心思想是:定义一个抽象的Command接口以执行命令.具体如何执行需要其子类ConcreteCommand来实现.ConcreteCommand在执行命令时必须借助于合适的接受该命令的对象,因此其维护一个Receiver指针.这样就能将命令调用者Invoker和命令的实际接收者Receiver进行解耦,调用者针对抽

设计模式--行为型模式--命令模式

=========================命令模式:========================= 废话不说了,先看例子: 模拟对电视机的操作有开机.关机.换台命令.代码如下 Command角色--定义命令的接口,声明执行的方法. 1 //执行命令的接口 2 public interface Command { 3 void execute(); 4 } Receive角色--命令接收者,真正执行命令的对象.实现命令要求实现的相应功能. 1 //命令接收者Receiver 2 pub

4周第3次课 vim 进入编辑模式 命令模式

进入编辑模式 即进入可以对文档进行编辑的模式 按键 作用 i 在当前字符插入 I 在光标所在行的行首插入 a 在当前字符后插入 A 在光标所在行的行尾插入 o 在光标所在行的下方插入一行 O 在光标所在行的上方插入一行 vim命令模式 命令 作用 /word 向光标之后查找一个字符串word,按 n 向后继续搜索,N向前返回搜索 ?word 向光标之前查找一个字符串word,按 n 向前继续搜索 :n1,n2s/word1/word2/g 在n1-n2行范围之间查找word1并替换为word2,

设计模式-行为型模式-策略模式

策略模式 在实际工作中我用到了策略模式,但为什么要有环境角色呢? 这里我贴上英文对含义的介绍, The Strategy Pattern defines a family of algorithms,encapsulates each one,and makes them interchangeable. Strategy lets the algorithm vary independently from clients that use it. 然后看看这种设计模式的组成, 一般的,策略模式

设计模式之命令模式学习理解

命令模式 命令模式(Command Pattern)是一种数据驱动的设计模式,它属于行为型模式.请求以命令的形式包裹在对象中,并传给调用对象.调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令. 介绍 意图:将一个请求封装成一个对象,从而使您可以用不同的请求对客户进行参数化. 主要解决:在软件系统中,行为请求者与行为实现者通常是一种紧耦合的关系,但某些场合,比如需要对行为进行记录.撤销或重做.事务等处理时,这种无法抵御变化的紧耦合的设计就不太合适. 何时使用:在某些