博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
设计模式-命令模式简单理解
阅读量:6791 次
发布时间:2019-06-26

本文共 2826 字,大约阅读时间需要 9 分钟。

这个模式的角色比较多:
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对象的耦合,有利于后续的扩展。
 
 
 
 
 

转载于:https://www.cnblogs.com/onetwothree/p/10210006.html

你可能感兴趣的文章
批处理之播放文本文件
查看>>
windows server 2008活动目录的备份与还原
查看>>
spring boot 2.0.1.RELEASE hibernate 缓存 ehcache 详解
查看>>
关于windows7的更新update失败,windows media play安装失败的 ...
查看>>
mysql之慢查询
查看>>
我的友情链接
查看>>
linux mysql 主主同步复制
查看>>
使用 ajax json(getJSON)从服务器读取数据,在IE下不更新问题解决
查看>>
Pythonの豆瓣相册下载脚本
查看>>
linux shell4 判断登陆用户,然后重启关闭系统
查看>>
《Cisco路由器配置与管理完全手册》(第二版)前言和目录
查看>>
git 删除本地分支
查看>>
关于SQL SERVER高并发解决方案
查看>>
MAVEN进行debug过程
查看>>
抓翻番股
查看>>
另一个视界 ——三星SUHD傲世超高清电视体验札记
查看>>
多维度创新打造领先阿里云技术生态
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
配置IEEE802.3X流控制
查看>>