设计模式之命令(Command)模式
???? Command定义如下: 将来自客户端的请求传入一个对象,无需了解这个请求激活的动作或有关接受这个请求的处理细节。
是不是有点迷糊。不知其说的是啥。哈哈。别着急下面听我慢慢到来。
?
本人觉得,命令模式就是把一些具体的命令封装成一此具体的类,这此类实现同一个接口或者是抽象类。然后把这些类组织到起,然后统一来执行,完成一个具体的业务流程。
?
它的优点是:解藉了发送者与接收者之间的联系。发送者调用一个操作,接收者接受请求执行相应的动作,说白了就是调用一个具体的类来执行相应的方法。因为使用Command模式解耦,发送者无需知道接受者任何接口。
比如说,对文件进行操作,如打开、关闭、打印。正常的操作就是用户点击“打开”按纽,就执行打开命令,在按纽的单击事件中写个方法就可以了。但如要应用Command模式,就要把其抽象出接口,把这三个操作封装成单独的类。也许有人要问,为什么要把简单的问题复杂化呢?。虽然在代码量上有所增加,这样做有利于代码的健壮性 可维护性 还有复用性。这是前人总结出来的经验。
?
说了半天,如何使用呢,别说费话了,“必需的”。
?
具体的Command模式代码各式各样,因为如何封装命令,不同系统,有不同的做法。
典型的Command模式需要有一个接口.接口中有一个统一的方法,这就是"将命令/请求封装为对象。
?
public interface Command { public abstract void execute ( );}
?
具体不同命令/请求代码是实现接口Command,下面有三个具体命令(打开命令、关闭命令、打印命令)
?
public class Open implements Command { public void execute( ) { System.out.println("打开"); }} public class Close implements Command { public void execute( ) { System.out.println("关闭"); }}public class Print implements Command { public void execute( ) { System.out.println("打印"); }}
?
按照通常做法,我们就可以直接调用这三个Command,但是使用Command模式,我们要将他们封装起来,扔到黑盒子List里去:
public class producer{ public static List produceRequests() { List queue = new ArrayList(); queue.add( new Open() ); queue.add( new Close() ); queue.add( new Print() ); return queue; }}
这三个命令进入List中后,已经失去了其外表特征,以后再取出,也可能无法分辨出谁是Open谁是Close了,看下面客户端如何调用Command模式:
public class TestCommand { public static void main(String[] args) { List queue = Producer.produceRequests(); for (Iterator it = queue.iterator(); it.hasNext(); ) //客户端直接调用execute方法,无需知道被调用者的其它更多类的方法名。 ((Command)it.next()).execute(); }}
?
由此可见,调用者基本只和接口打交道,不合具体实现交互,这也体现了一个原则,面向接口编程,这样,以后增加第四个具体命令时,就不必修改调用者TestCommand中的代码了.
理解了上面的代码的核心原理,在使用中,就应该各人有自己方法了,特别是在如何分离调用者和具体命令上,有很多实现方法,上面的代码是使用"从List过一遍"的做法.这种做法只是为了演示.