js设计模式系列篇:命令(Command)模式

152 阅读2分钟

什么是命令模式

命令模式是指将方法的调用等操作封装到单一的对象中,将调用操作的对象与知道如何实现该操作的对象解耦,为系统提供更大的灵活性。

上面的描述很绕口,我们不妨来看一个例子

const car = {
    getInfo: (model, id) => {
        console.log(`the information for ${model} width ID:${id} is foo`)
    },
    buy: (model, id) => {
        console.log(`you have buy the ${model} with ID:${id}`)
    }
}

上面的代码没有任何问题。但是,想想如果car里的某个方法改变了会怎么样。这可能会要求我们将程序中所有调用这些方法的地方都改一遍。这就形成了一个紧密耦合,违反了OOP原则中的松耦合原则。

这时候,我们就可以用到命令模式了。我们可以在car中再编写一个方法,这个方法接受car中的任意方法名和任何需要用到的参数,调用方式如下

car.execute('getInfo', 'Tesla', 1)

一般,命令模式都会包含类似的执行操作(execute, run),我们可以将其看成是一个对car对象的命令,命令car执行某个函数。

现在实现一下execute方法,非常简单

const car = {
    getInfo: (model, id) => {
        console.log(`the information for ${model} width ID:${id} is foo`)
    },
    buy: (model, id) => {
        console.log(`you have buy the ${model} with ID:${id}`)
    },
    execute: (methodName, ...rest) => {
        car[methodName] && car[methodName].apply(car, rest)
    }
}
car.execute('getInfo', 'Tesla', 1)
car.execute('buy', 'Honda', 2)

执行上面的代码,在控制台看到如下输出

image.png

说明execute方法运行正常。

总结

命令模式通过暴露一个统一的执行接口,来提高系统的可维护性和灵活性。我们也可以将其与模块模式相结合,隐藏其余所有的方法,只对外暴露一个公用接口。在多人协作的项目中相信可以有效减少沟通成本,使得代码更加统一,简洁。

下面给出一个简单的模块模式的实现,大家可以试一下如何将其与命令模式结合

const myModule = (function () {
    //私有变量
    let myPrivate = 0

    //私有方法
    const privateMethod = (foo) => {
        console.log(foo)
    }

    return {
        publicFunction: (bar) => {
            myPrivate++
            privateMethod(bar)
        }
    }
})()

myModule.publicFunction('baz')