设计模式-命令模式简单理解

这个模式的角色比较多:
Command:接口定义,只包含一个do方法,子类实现调用对应的Receiver的操作
Client:负责创建Command对象;传递Command对象给Invoker。
Invoker:执行Command对象的do操作。
Receiver:命令的实际执行者。
 
举个非常简单的例子:客户要求实现一个格式化工具,只包含一个按钮Format和一个菜单项Open用来打开文件。
另外客户给我们提供了格式化的实现类:
class XMLObject{
    private String content;
    public XMLObject(String fileName){
        content=文件内容;
    }
    public void formatXML(){
        content=格式化后的文件内容
    }
    public void saveXML(){
        //保存content到文件
    }
}

 

根据需求我们可以按照下面的操作流程开发:
(1)点击Open菜单:选择文件,创建XMLObject对象;
(2)点击Format按钮:调用XMLObject对象的fotmatXML方法和saveXML方法。
接下来,代码怎么编写呢?
(1)实现Open菜单的功能:
Object currentObject = new XMLObject(filename);
(2)实现format按钮功能:
currentObject.format();
currentObject.save();
嗯,代码看上去比较简单。
 
后续需求:客户又提供了JSONObject、SQLObject类,让我们实现。
于是,我们这样做:
(1)实现Open菜单的功能:
if(文件后缀==.XML) Object currentObject = new XMLObject(filename);
else
 if(文件后缀==.JSON) Object currentObject = new JSONObject(filename);
else 
if(文件后缀==.SQL) Object currentObject = new SQLObject(filename);
(2)实现format按钮功能:
if(currentObject instanceof XMLObject ){
    currentObject.formatXML();
    currentObject.saveXML();
    return;
}
if(currentObject instanceof JSONObject ){
    currentObject.formatJSON();
    currentObject.saveJSON();
    return;
}
if(currentObject instanceof SQLObject ){
    currentObject.formatSQL();
    currentObject.saveSQL();
    return;
}
可以看到,每增加一个类型的文件支持,就要format按钮的代码,随着类型的不断增加,format的判断条件会越来越多,并且二者耦合在一起。
 
如何去耦合?
(1)可以定义一个接口
interface FormatCommand{
    do();
}

然后让format按钮调用Command.do();这样再来了新的对象我就不用修改format操作了,而且再新增其他的按钮,比如unformat,undo等我也可以这样做。

 
(2)创建三个命令类:
class XMLFormatCommand implements FormatCommand{
    XMLObject currentObject;
    public XMLFormatCommand(XMLObject obj){
        currentObject = obj;
    }
    public  do(){
        currentObject.formatXML();
        currentObject.saveXML();
    }
}
class JSONFormatCommand implements FormatCommand{
    JSONObject currentObject;
    public JSONFormatCommand(JSONObject obj){
        currentObject = obj;
    }
    public do(){
        currentObject.formatJSON();
        currentObject.saveJSON();
    }
}
class SQLFormatCommand implements FormatCommand{
    SQLObject currentObject;
    public SQLFormatCommand(SQLObject obj){
        currentObject = obj;
    }
    public do(){
        currentObject.formatSQL();
        currentObject.saveSQL();
    }
}
(3)实现Open菜单的功能:
if(文件后缀==.XML) FormatCommand currentCommand = new XMLFormatCommand(XMLObject(filename));
else
 if(文件后缀==.JSON) FormatCommand currentCommand = newJSONFormatCommand(JSONObject(filename));
else 
if(文件后缀==.SQL) FormatCommand currentCommand =new JSONFormatCommand(JSONObject(filename));
(4)实现format按钮功能:
currentCommand.do();
其实这就是命令模式:
 
Client:打开菜单
Invoker:format按钮
Receiver:三个Object
Command:FormatCommand三个实现
 
思考:
这样有什么好处呢?代码也没减少啊?
 
是的,代码量没有减少,不过这样符合了代码的开闭原则,去除了format按钮和用户提供的Object对象的耦合,有利于后续的扩展。
 
 
 
 
 

posted on 2019-01-03 10:12  SimpleWorker  阅读(147)  评论(0编辑  收藏  举报

导航