行为型模式:命令模式

LieBrother原文:
行为型模式:命令模式java

景

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

简介

姓名 :命令模式git

英文名 :Command Patterngithub

价值观 :军令如山设计模式

我的介绍ide

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

你要的故事

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

非命令模式

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

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,第一时间获取文章推送阅读,也能够一块儿交流,交个朋友。

公众号

相关文章
相关标签/搜索