经典设计模式——命令模式

简介:

    考虑这样一种场景,某个方法需要完成某一个功能,完成这个功能的大部分步骤已经确定了,但可能有少量具体步骤无法确定,必须等到该方法执行时才可以确定。具体一点:假设有个方法需要遍历某个数组的数组元素,但无法确定在遍历数组元素时如何处理这些元素,需要调用该方法时指定具体的处理行为。这个要求看起来有点奇怪:这个方法不仅要求传入参数可以变化,甚至要求方法执行体的代码也可以变化,难道我们能把“处理行为”作为一个参数传入该方法?

    很遗憾,Java语言暂时还不支持将代码块作为参数传递给方法。

    对于这样的要求,我们必须把“处理行为”作为参数传入该方法,而“处理行为”用编程来实现就是一段代码。那如何把这段代码传入某个方法呢?

    因为Java不允许代码块单独存在,因此我们必须把该代码块封装成一个方法。在Java中,方法不能独立存在,类才是可以独立存在的,所以我们传入该方法的应该是一个对象,该对象通常是某个接口的匿名实现类的实例,该接口通常被称为命令接口,这种设计模式也被称为命令模式。

    下面的程序先定义一个ProcessArray类,该类里包含一个each()方法用于处理数组,但具体如何处理暂时不能确定,所以each()方法里定义了一个Command参数:

?
1
2
3
4
5
public  class  ProcessArray {
     pubic  void  each( int [] targetArray, Command cmd) {
         cmd.process(targetArray);
     }
}

    上面的each方法有一个Command类型的cmd参数,这个Command接口用于定义一个process()方法,该方法用于封装对数组的“处理行为”,下面是Command接口的代码:

?
1
2
3
public  interface  Command {
     public  void  process( int [] targetArray);
}

    上面的Command接口里定义了一个process方法,这个方法用于封装“处理行为”,但这个方法没有方法体——因为现在还无法确定这个处理行为。

    当主程序调用ProcessArray对象的each()方法来处理数组时,每次处理数组需要传入不同的“处理行为”——也就是要为each()方法传入不同的Command对象,不同的Command对象封装了不同的“处理行为”。下面是主程序调用ProcessArray对象each()方法的程序:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public  class  CommandTest {
     public  static  void  main(String args[]) {
         ProcessArray processArray =  new  ProcessArray();
         int [] target = { 1 , 2 , 3 ,- 4 };
         //第一次处理,其处理行为取决于Command对象
         processArray.each(target,  new  Command() {
             @Override
             public  void  process( int [] targetArray) {
                 int  sum =  0 ;
                 for  ( int  i:targetArray) {
                     sum += i;
                 }
                 System.out.println( "数组元素的和为:"  + sum);
             }
         });
         System.out.println( "=================================" );
         //第二次处理,其处理行为取决于Command对象
         processArray.each(target,  new  Command() {
             @Override
             public  void  process( int [] targetArray) {
                 int  max =  0 ;
                 for  ( int  i:targetArray) {
                     if ( max < i) {
                         max = i;
                     }
                 }
                 System.out.println( "数组元素的最大值为:"  + max);
             }
         });
     }
}

    正如上面的代码所示:程序两次调用ProcessArray对象的each()方法来处理数组对象,每次调用时传入不同的Command实现类的实例,不同的Command实例封装了不同的“处理行为”。运行上面的程序,可以看到以下结果:

    上图显示了两次不同处理行为的执行结果,也就实现了process方法和“处理行为”的分离,两次不同的处理行为分别由两个不同的Command对象来提供。

    理解了这个命令模式后,我们再看看Spring框架中HibernateTemplate的executeXxx()方法。这个方法弥补了HibernateTemplate的不足,该方法需要接受一个HibernateCallback接口,该接口的代码如下:

?
1
2
3
public  interface  HibernateCallback {
     Object doInHibernate(Session session);
}

    上面的HibernateCallback接口就是一个典型的Command接口,一个HibernateCallback对象封装了自定义的持久化处理。对Hibernate而言,大部分持久化操作都可以通过一个方法来实现,HibernateTemplate对象简化了Hibernate的持久化操作,但丢失了使用Hibernate持久化操作的灵活性。

    通过HibernateCallback就可以弥补HibernateTemplate灵活性的不足,当调用HibernateTemplate的executeXxx()方法时,传入HibernateCallback对象的doInHibernate()方法就是自定义的持久化处理——即将自定义的持久化处理传入executeXxx()方法,如下面的代码所示:

?
1
2
3
4
5
6
7
8
9
10
11
12
List list = getHibernateTemplate().executeFind( new  HibernateCallback(){
     //实现HibernateCallback接口的方法
     @Override 
     public  Object doInHibernate(Session session) {
         //执行自己的代码
         List result = session.createQuery(hql)
             .setFirstResult(offset)
             .setMaxResults(pageSize)
             .list();
         return  result;
     }
});

    上面的程序中将自定义的方法传给HibernateTemplate,HibernateTemplate将直接使用这段代码来执行查询,并将查询结果作为executeFind()方法的返回值。这也是一个典型的命令模式的例子。

目录
相关文章
|
6月前
|
设计模式 UED
二十三种设计模式:解锁软件开发的神器:命令模式与撤销重做功能
二十三种设计模式:解锁软件开发的神器:命令模式与撤销重做功能
153 0
|
2月前
|
设计模式 存储 算法
Java设计模式-命令模式(16)
Java设计模式-命令模式(16)
|
3月前
|
设计模式 存储 Java
【十二】设计模式~~~行为型模式~~~命令模式(Java)
文章详细介绍了命令模式(Command Pattern),这是一种对象行为型模式,用于将请求封装成对象,实现请求发送者与接收者的解耦,从而降低系统耦合度、提高灵活性,并支持命令的排队、记录、撤销和恢复操作。通过案例分析、结构图、时序图和代码示例,文章展示了命令模式的组成部分、实现方式和应用场景,并讨论了其优点、缺点和适用情况。
|
4月前
|
设计模式 JavaScript API
js设计模式【详解】—— 命令模式
js设计模式【详解】—— 命令模式
42 6
|
5月前
|
设计模式
命令模式-大话设计模式
命令模式-大话设计模式
|
5月前
|
设计模式 Java uml
必知的技术知识:JAVA【设计模式】命令模式
必知的技术知识:JAVA【设计模式】命令模式
27 0
|
5月前
|
设计模式 Java
Java设计模式之命令模式详解
Java设计模式之命令模式详解
|
5月前
|
设计模式
设计模式之命令模式
设计模式之命令模式
|
6月前
|
设计模式 Java 调度
【设计模式系列笔记】命令模式
命令模式是一种行为设计模式,它将请求封装成一个对象,从而允许使用不同的请求、队列或日志请求参数化客户端对象,同时支持撤销操作。
63 1
|
6月前
|
设计模式 Java 调度
小谈设计模式(24)—命令模式
小谈设计模式(24)—命令模式

热门文章

最新文章