JiveJdon Community Forums
在线206人   首页   主题总表   培训咨询   精华   查搜   注册    登陆
首页 » 论坛 » J2EE/JavaEE/JEE/EJB/JSF等技术讨论
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表
???en_US.forumThreadNext.name??? 下一主题
1 2 Go 总共有 17 回复 / 2
 发表新帖子   回复该主题贴
xyz

悄悄话
发表文章: 80
注册时间: 2005年08月22日 20:17
命令模式(我的理解) 2006年04月12日 22:55 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
标签列表 command模式(6)     
命令模式(我的理解)
前言
第一章:通常的命令模式
第二章:简化的命令模式
第三章:其他要说的内容
前言
以下是我对命令模式的理解。可能和很多其他文章讲述的不太一样。经过我理解加工的。供大家参考!学艺不精,并且写的比较仓促,还请大家指教。
通常的命令模式:
1.1通常命令模式有一下几个角色
调用者:(命令的执行者)
生成有序的命令队列
按顺序执行命令操作
提供撤销命令操作
记录已经操作的命令
抽象命令:
抽象的命令接口
具体命令:
具体的命令。
由三个要素组成:执行者,执行者要作的操作和被执行的对象组成。当然还可以有其他,比如将对象执行成什么结果。例如:调用Mypait类(执行者)将My rectangle(对象)填充(操作)为红色(结果)。这样就可以完全描述一个命令了。
执行者:
真正执行逻辑操作的对象

1.2原型:

//调用者
public class Invoker{
List commands; //命令集合

public void setCommands(List commands){
this.commands = commands;
}

public void addCommand (Command command,int i){
commands.add(i,command);
}
public void removeCommand (int i){
commands.add(i,command);
}
//得代执行命令
public void action(){
for(Iterator it = list.iterator();it.hasNext();){
Command command = Command) it.next();
Command. execute();
}
}
……………
//还可以有丰富的redo和undo操作;(当然一些都给基于命令类提供的相应方法)
}

//抽象命令
abstract class Command
{
abstract public void execute();
abstract public void unexecute();
abstract public void reexecute();
//一般有这样这个方法,根据需要可以增删
}

// 具体的命令类1:写作命令,选择一个作者(Author类实例对象),让他写作(调用它的write方法)写作的对象是书(Book的实例对象)形成了一个写作的命令,写作的对象是Book的实例
public class WriteCommand implement Command
{
Author author; //执行者
Book book; //要执行的对象
public WriteCommand (Author author,Book book) {
this. author = author;
this. book = book;
}
// 在这里执行要执行的操作
public override void Execute()
{
author.write (book);
}
}

// 具体的命令类2: 出版命令,选择一个出版社(publisher类实例对象),让他出版书(调用它的publisherBook方法)出版的对象是书(Book的实例对象)形成了一个出版的命令
public class PublishCommand implement Command
{
Publisher publisher;
Book book;
public PublishCommand (Publisher publisher) {
this. publisher = publisher;
this. book = book;
}
// Methods
public override void Execute()
{
publisher. publisherBook(book);
}
}

// Publisher和Author类为执行者


这样我们的客户端代码就可以这样写:
//如果我要出一本书
//一本空白的书
Book book = new Book();
//先找一个作者和出版社
Author author = new Author();
Publisher publisher = new Publisher ();
//产生命令集合
Command writeCommand = new WriteCommand (author,book);
Command publishCommand = new PublishCommand(publisher,book);
List commands = new List ();
Commands.add(writeCommand);
//找个调用者,把命令给它,让他来根据命令协调工作
Invoker invoker = new invoker();
Invoker.setCommands(commands);
public void addCommand (Command command,int i){
commands.add(i,command);
}
invoker.action();

特点:
1》 分布登记统一执行:
在作程序时,经常碰到一些需求,先注册一些操作,并不马上执行,等最终确定后统一执行。如一个具体的例子:用户定制自己的报表,可以订阅饼,柱,折线,曲线图,客户选择相应的报表组合,这样对应一个命令集合,在没确定之前用户可以增删这些报表(命令),等最终确定统一交给调用者根据命令执行,生成组合报表。实现了命令分布提出,确定后统一执行的功能。

2》形如流水线操作:还是出书的例子
//先是一本空白的书:
Book book = new Book();
//找几个作者
Author author1 = new Author();
Author author2 = new Author();
//把写1,2章的名类分别给这两个作者
Command writeCommand = new Write1Command (author1,book);
Command writeCommand = new Write2Command (author2,book);
List commands = new List ();
Commands.add(writeCommand);
//调用者
Invoker invoker = new invoker();
Invoker.setCommands(commands);
//流水写书
invoker.action()
实际上在aciton这一方法中,invoker按照命令,让两个作者流水写作这本书。(类似一个书的流水线加工工厂)
这样我们的书就被流水加工成功(当然这本书只有两章)

这样就给了我们一种系统设计的框架,
模型+工具+命令
客户端产生命令,命令调用工具操作模型。
Book 相当于模型
Author 相当于和多工具类中的一个
Command 命令

3》系统需要支持命令的撤消(undo)。提供redo()方法
我们可以和容易的加入undo和redo,这个不难理解

4》在Invoker中我们可以实现跟踪,和日志。

5》当系统需要为某项复制增加形的功能的时候,命令模式使新的功能(表现为一种命令)很容易地被加入到服务种里。
命令联系了工具类即执行类和系统逻辑,

简化/变化的命令模式:
命令模式的角色比较多,在实际应用种我们可以根据所需要的功能和不需要的功能加以简化。

1》去掉 调用者
产生命令集合后,我们可以直接在client中迭代执行执行操作
2》 变化 调用者 成为 跟踪者
//调用者
public class Invoker{
List commands; //已经执行完毕的命令集合
public void addCommand (Command command,int i){
commands.add(i,command);
}
public void action(Command command){
//执行操作
command. execute();
//
commands.add(command);
}
}
……………
//还可以有丰富的redo和undo操作;(当然一些都给基于命令类提供的相应方法)
}
这样这个类就记录了所有执行过的操作。

3》去掉 命令 用map替代
我们完全可以用map代替命令,这样无需定义各种命令类
我们改进例子
Author author = new Author();
Publisher publisher = new Publisher ();
Map m = new HashMap;
m.put(author, write);
m.put(author, publisherBook);
在Invoker的action方法:
得代map
运用java反射来调用方法;

4》去掉执行者:
直接在命令中(execute方法种)加业务逻辑。这样只适合于简单的小的系统.

其他要说的内容
1》 将某些参数传给某个方发的方式很多,除了当作方法的参数外还可以当作类的成员便俩变量传入:
这就为命令的抽象带来了极大的方便
abstract class Command
{
abstract public void execute();
}
当我们已经有了执行者(类Test)方法execute(args1,args2 ….argsn)
我们不必向Command加入execute(args1,args2 ….argsn)抽象方法,在说即使加了,在我们迭代的时候也无法判断或十分不容易判断哪个命令调用哪个execute方法。
那么我们可以这样
class ConcreteCommand : Command
{
Test test;
args1
args2
…..
argsn
public override void Execute()
{
test. execute (args1,args2 ….argsn);
}
}
2》 在想跟踪操作的时候,一般为每一个操作对象分配一个调用者,操作对象在调用者中设置。(可以抽象出一个总的调用者,来协调调用每一个具体的调用者)
3》 命令的抽象粒度我觉得是要注意的。
4》 理解思想,不要机械的照搬。消化成自己的,加以灵活的运用和创造在是根本出路。
所谓命令模式的根本思想就是在 先形成命令,在根据命令执行。
banq

悄悄话
发表文章: 9312
注册时间: 2002年08月03日 17:08
Re: 命令模式(我的理解) 2006年04月13日 15:56 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
不错,实际是一个群命令的使用,单个命令模式粒度太小,让人难以把握,但是多个命令群集合在一起就感觉命令模式的作用。

该文群命令一种用法(流水线操作)实际展示了命令模式+职责链的使用,或者说命令组成的Filter过滤器模式,这种方式可以重构if else逻辑。

使用Map的群命令也是常用的一种过滤器实现,这种方式性能好,也可以重构原来的if else逻辑。

可结合本人的"你还在用if else吗?":
http://www.jdon.com/artichect/ifelse.htm
xyz

悄悄话
发表文章: 80
注册时间: 2005年08月22日 20:17
Re: 命令模式(我的理解) 2006年04月14日 17:05 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我觉得命令+组合+责任链比较好用,组合模式的加入,可以使得我们的命令可以随意组合,重用!
zjq545

悄悄话
发表文章: 1
注册时间: 2006年05月21日 20:15
Re: 命令模式(我的理解) 2006年05月21日 20:19 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
理解的很透彻,不光是讲了概念还 说了具体怎么用。这样才是学以至用
adsedfs

悄悄话
发表文章: 1
注册时间: 2006年05月21日 22:45
Re: 命令模式(我的理解) 2006年05月21日 22:47 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
顶`````
angelzll

悄悄话
发表文章: 1
注册时间: 2006年05月21日 22:47
Re: 命令模式(我的理解) 2006年05月21日 22:49 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
写的不错,加深了我对命令模式的理解!
marionette

悄悄话
发表文章: 1
注册时间: 2006年05月22日 08:45
Re: 命令模式(我的理解) 2006年05月22日 08:49 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
楼主的话真如“大音希声扫阴翳”,犹如”拨开云雾见青天”,使我等网民看到了希望,看到了未来!晴天霹雳,醍醐灌顶或许不足以形容楼主文章的万一;巫山行云,长江流水更难以比拟大师的文才!黄钟大吕,振聋发聩!你烛照天下,明见万里;雨露苍生,泽被万方!透过你深邃的文字,我仿佛看到了你鹰视狼顾,龙行虎步的伟岸英姿;仿佛看到了你手执如椽大笔,写天下文章的智慧神态;仿佛看见了你按剑四顾,江山无数的英武气概!
最后感叹一句:我靠,精辟呀!~
liu3

悄悄话
发表文章: 1
注册时间: 2006年05月24日 22:06
Re: 命令模式(我的理解) 2006年05月24日 22:11 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
本来想提点意见,结果每看明白.
xyz

悄悄话
发表文章: 80
注册时间: 2005年08月22日 20:17
Re: 命令模式(我的理解) 2006年05月25日 22:24 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
我已经尽量把命令模式说的很明白了,您仍然不明白的话,我感到遗憾!
power1128

悄悄话
发表文章: 52
注册时间: 2006年05月24日 14:37
Re: 命令模式(我的理解) 2006年05月27日 09:33 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
小弟初学,不过也看的明白,挺好懂。不过有些地方有错别字和代码错误

比如这个:应该是remove吧
public void removeCommand (int i){
commands.add(i,command);
}

这里也少个参数哈
public PublishCommand (Publisher publisher) {
this. publisher = publisher;
this. book = book;
}
tempaccount

悄悄话
发表文章: 7
注册时间: 2005年05月05日 14:14
Re: 命令模式(我的理解) 2006年06月02日 09:56 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
受教
seu09

悄悄话
发表文章: 1
注册时间: 2006年08月25日 17:43
Re: 命令模式(我的理解) 2006年08月25日 17:47 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
小弟是初学者,但是看过之后觉得学到了很多!!!!!
einstein

悄悄话
发表文章: 1
注册时间: 2007年01月11日 17:09
re:命令模式(我的理解) 2007年01月11日 17:09 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
Command writeCommand = new Write1Command (author1,book);
Command writeCommand = new Write2Command (author2,book);
List commands = new List ();
Commands.add(writeCommand);


这里是否有问题?

我感觉应该是这样的吧!

Command write1Command = new WriteCommand (author1,book);
Command write2Command = new WriteCommand (author2,book);
List commands = new List ();
Commands.add(write1Command);
Commands.add(write2Command);


cljspn

悄悄话
发表文章: 4
注册时间: 2008年03月16日 16:57
回复:re:命令模式(我的理解) 2008年03月19日 09:09 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题


public PublishCommand (Publisher publisher) {
this. publisher = publisher;
this. book = book;
}

是不应该这样呢。

public PublishCommand (Publisher publisher,Book book) {
this. publisher = publisher;
this. book = book;
}
xmuzyu

悄悄话
发表文章: 130
注册时间: 2007年03月26日 12:16
re:命令模式(我的理解) 2008年07月30日 20:24 到本帖网址 加入本帖到收藏夹 发送到手机 回复该主题
同意命令+组合+责任链的说法,这样确实很好用。一个宏命令确实可以实现责任链。
这个主题有 17 回复 / 2Go 1 2
???en_US.forumThreadPrev.name??? 上一主题
  Go back to the topic 返回本主题   Go back to the topic listing返回主题列表    返回页首返回页首
???en_US.forumThreadNext.name??? 下一主题
热点TAG: AOP cache 缓存 DDD EJB 集群 设计模式 Hibernate IOC JiveJdon OO RBAC Seam Spring Struts
正在读取,请等待...
google yahoo 新浪ViVi 365Key网摘 天极网摘 CSDN网摘 添加到百度搜藏 POCO网摘 博采网摘
查询本论坛内 回复超过的热门帖子
     回复该主题贴
标题
 
粗体 斜体 下划线 插入图片 插入代码 插入url链接 插入附件
内容
 

手机阅读 add to google add to yahoo
解惑之道在J道 ,打造中国最具影响力的的企业软件社区
OpenSource JIVEJDON v3.0 Powered by JdonFramework Code © 2002-08 jdon.com
anti spam