溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊(cè)×
其他方式登錄
點(diǎn)擊 登錄注冊(cè) 即表示同意《億速云用戶(hù)服務(wù)條款》

行為型模式:命令模式

發(fā)布時(shí)間:2020-06-24 13:52:11 來(lái)源:網(wǎng)絡(luò) 閱讀:277 作者:LieBrother 欄目:軟件技術(shù)

文章首發(fā):
行為型模式:命令模式

行為型模式:命令模式

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

簡(jiǎn)介

姓名 :命令模式

英文名 :Command Pattern

價(jià)值觀 :軍令如山

個(gè)人介紹

Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests,and support undoable operations.
將一個(gè)請(qǐng)求封裝成一個(gè)對(duì)象,從而讓你使用不同的請(qǐng)求把客戶(hù)端參數(shù)化,對(duì)請(qǐng)求排隊(duì)或者記錄請(qǐng)求日志,可以提供命令的撤銷(xiāo)和恢復(fù)功能。
(來(lái)自《設(shè)計(jì)模式之禪》)

你要的故事

作為一個(gè)程序猿,我們每天都在經(jīng)歷著命令模式,技術(shù)經(jīng)理把需求任務(wù)分配給工程師開(kāi)發(fā),有時(shí)因?yàn)榈谌交蛘咂渌豢煽咕艿囊蛩貙?dǎo)致需求停止開(kāi)發(fā)。這種工作模式就是命令模式。好了,開(kāi)始故事了。小明在 XX 科技公司做一個(gè)安靜的程序猿,有一天技術(shù)經(jīng)理給他分配了一個(gè)任務(wù):新增黑名單,也就是在他們系統(tǒng)的某個(gè)模塊里面可以手工對(duì)電話(huà)打黑名單標(biāo)簽的功能。小明接到任務(wù)后就立馬開(kāi)發(fā),在開(kāi)發(fā)了 2 天之后,因?yàn)閼?zhàn)略原因,技術(shù)經(jīng)理大明暫停了這個(gè)開(kāi)發(fā)任務(wù),接下來(lái)我們通過(guò)非命令模式和命令模式 2 種代碼實(shí)現(xiàn)來(lái)體現(xiàn)這個(gè)過(guò)程。在這個(gè)場(chǎng)景中,為了簡(jiǎn)單,我們假定技術(shù)經(jīng)理大明手下只有小明一個(gè)開(kāi)發(fā)人員。

非命令模式

非命令模式也就是不使用命令模式的代碼實(shí)現(xiàn)。代碼中,我們出現(xiàn)了 Developer 開(kāi)發(fā)人,開(kāi)發(fā)同學(xué)是接受技術(shù)經(jīng)理傳達(dá)的任務(wù),技術(shù)經(jīng)理讓他開(kāi)發(fā)哪個(gè)需求就開(kāi)發(fā)哪個(gè)需求,如果項(xiàng)目有問(wèn)題需要中斷,也需要技術(shù)經(jīng)理評(píng)估后傳達(dá)給開(kāi)發(fā)同學(xué),所以 Developer 有 2 個(gè)方法,分別是 develop() 開(kāi)發(fā)需求和 suspend() 暫停需求。 Requirement 則為需求類(lèi),TechnicalManager1 則為技術(shù)經(jīng)理類(lèi),他有一個(gè)方法 action(),通過(guò)這個(gè)方法來(lái)指定開(kāi)發(fā)同學(xué)開(kāi)發(fā)任務(wù)或者暫停任務(wù)。

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("開(kāi)發(fā)了 2 天,需求變故,需要暫停。。。");
        technicalManager2.action(requirement, "suspend");
    }

}

/**
 * 開(kāi)發(fā)人員
 */
class Developer {

    private String name;

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

    public void develop(Requirement requirement) {
        System.out.println(this.name + " 開(kāi)始開(kāi)發(fā)需求:" + requirement.getName());
    }

    public void suspend(Requirement requirement) {
        System.out.println(this.name + " 停止開(kāi)發(fā)需求:" + requirement.getName());
    }

    public String getName() {
        return name;
    }

}

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

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

    public String getName() {
        return name;
    }

}

/**
 * 技術(shù)經(jīng)理
 */
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);
        }
    }

}

打印結(jié)果:
小明 開(kāi)始開(kāi)發(fā)需求:新增黑名單
開(kāi)發(fā)了 2 天,需求變故,需要暫停。。。
小明 停止開(kāi)發(fā)需求:新增黑名單

通過(guò)代碼,我們可以發(fā)現(xiàn)技術(shù)經(jīng)理和開(kāi)發(fā)同學(xué)是強(qiáng)依賴(lài)關(guān)系。如果技術(shù)經(jīng)理下達(dá)了一個(gè)任務(wù),要求小明寫(xiě)一下周報(bào),這時(shí)候得怎么寫(xiě)?是不是小明需要一個(gè)寫(xiě)周報(bào)的方法,大明也需要新增一個(gè)處理事務(wù)類(lèi)型?有沒(méi)有更好的方法讓技術(shù)經(jīng)理不需要做任何改變?命令模式就來(lái)解決這個(gè)問(wèn)題。

命令模式

在這個(gè)例子中,不管大明叫小明做什么事情,其實(shí)都是一樣的,就是下達(dá)任務(wù)命令,讓小明去執(zhí)行命令。我們可以利用命令模式把下達(dá)任務(wù)這個(gè)抽象起來(lái),當(dāng)做父類(lèi),下達(dá)開(kāi)發(fā)命令、下達(dá)暫停命令、下達(dá)寫(xiě)周報(bào)等等都是不同的子命令。代碼如下。

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("開(kāi)發(fā)了 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);
}

/**
 * 開(kāi)始開(kāi)發(fā)
 */
class DevelopCommand extends Command {

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

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

/**
 * 開(kāi)發(fā)中斷
 */
class SuspendCommand extends Command {

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

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

/**
 * 技術(shù)經(jīng)理
 */
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;
    }
}

打印結(jié)果:
小明 開(kāi)始開(kāi)發(fā)需求:新增黑名單
開(kāi)發(fā)了 2 天,需求變故,需要暫停。。。
小明 停止開(kāi)發(fā)需求:新增黑名單

代碼中用 Command 來(lái)抽象下達(dá)任務(wù),而技術(shù)經(jīng)理 TechnicalManager2 并沒(méi)有和 Developer 有直接的關(guān)系,而是 TechnicalManager2 和 Command 建立的聯(lián)系,Command 和 Developer 建立了聯(lián)系。這樣子把大明和小明的強(qiáng)依賴(lài)關(guān)系給剝離開(kāi),而新增一個(gè)下達(dá)寫(xiě)周報(bào)的任務(wù)也很簡(jiǎn)單,在 Developer 中新增一個(gè)處理寫(xiě)周報(bào)的方法,新增一個(gè)寫(xiě)周報(bào)的 Command 子類(lèi),就可以了,TechnicalManager2 如上面所愿不用修改。這就是完整的一個(gè)命令模式代碼。

代碼:
Command Pattern

總結(jié)

從文章中我們就可以看到,利用命令模式能夠進(jìn)行類(lèi)的解耦,讓調(diào)用者和接受者沒(méi)有任何關(guān)系,也通過(guò)對(duì)行為的抽象,讓新增其他行為變得清晰容易,也就是可擴(kuò)展性大大增加。

推薦閱讀

創(chuàng)建型模式:?jiǎn)卫J剑ㄐ∶骶椭挥?1 輛車(chē))
創(chuàng)建型模式:工廠方法(小明家的車(chē)庫(kù))
創(chuàng)建型模式:抽象工廠(寶馬車(chē)就得用寶馬輪胎和寶馬方向盤(pán))
創(chuàng)建型模式:建造者模式(湯這么煲)
創(chuàng)建型模式:原型模式(復(fù)印書(shū)籍)
行為型模式:模板方法(運(yùn)動(dòng)鞋制造過(guò)程)
行為型模式:中介者模式(租房找中介)

公眾號(hào)后臺(tái)回復(fù)『大禮包』獲取 Java、Python、IOS 等教程
加個(gè)人微信備注『教程』獲取架構(gòu)師、機(jī)器學(xué)習(xí)等教程

行為型模式:命令模式

向AI問(wèn)一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如果涉及侵權(quán)請(qǐng)聯(lián)系站長(zhǎng)郵箱:is@yisu.com進(jìn)行舉報(bào),并提供相關(guān)證據(jù),一經(jīng)查實(shí),將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI