行为型模式:命令模式(Command Pattern)

Command Pattern(命令模式)

:概述

   在软件实现过程中,“行为的请求者”和“行为的实现者”通常是紧耦合的。命令模式的目的就是把中间的命令封装成一个对象,实现"行为请求者",和“行为实现者”之间的松耦合。

首先它是行为模式(behavioral design pattern)。命令模式也叫(Transaction Pattern)事务模式,Action 模式。

命令模式是对命令的封装,用户程序使用的时候,请求方(Invoker)只与命令(Command)进行交互,让命令(Command)同接收命令的对象(Receiver)交互。降低了请求(Invoker)方与接收方(Command)的耦合度。

命令模式使“行为请求者”和“行为实现者”独立开来,使得“行为请求者”不必知道“行为实现者”使用的接口。更不必知道请求是怎么被接收,以及操作是否被执行、何时被执行,以及是怎么被执行的。

二:模式结构

命令模式设计到了5个角色:

Client(客户):创建具体命令(ConcreteCommand)对象和命令的接收者(Receiver);

Command(命令):声明一个给具体命令实现的接口或者抽象类。

ConcreteCommand(具体命令):义一个接受者和行为之间的弱耦合;实现Execute()方法,负责调用接收考的相应操作。Execute()方法通常叫做执方法。

Invoker(行为请求者):调用命令对象执行请求。

Receiver(行为实现者):具体实施一个请求。

三:命令模式的优点

                 具体的命令可以被不同的请求者角色重用

      容易构造命令队列(多个命令装配程一个复合命令)

      增加新的命令很容易,因为无须改变现有的类

      记录相关的命令日志

      增加命令状态,实现命令的撤销(undo)和重做(redo)

      允许接收请求的一方决定是否可做

四:命令模式的缺点

      因为针对每一个命令都要设计一个具体的命令类,会导致系统内有过多的命令类。

五:适用场合

1,  Transactional behavior(事务行为)

      a) 使用命令模式,可以简单的实现以下事务行为,当一个事务失败,回退到之前的状态,可以使用命令保存这种状态,简单的处理回退操作。

2,  Swing中,工具条上按钮执行的命令,可以用command来封装这些命令(All implementations of javax.swing.Action)

3,  (Thread pools)线程池之中,Runnable就相当于一个命令接口(Command),实现它相当于一个具体命令(ConcreteCommand)。线程池类相当于调用者(Invoker)(All implementations of java.lang.Runnable)

4,  Macro  Record(宏记录)

      a)  可以通过command简单的封装用户的一个操作,系统就可以通过队列来保存一些类的用户操作。通过执行队列的操作,可以执行返回操作。

5,  Network

     a) 通过网络可以发送命令到其他机器上运行

6,  Struts中的Action  ,已登陆为例,Action就相当于一个命令接口,实现LoginAction的类为具体命令,当jsp页面发送一login个请求,执行LoginAction(具体命令)中的 execute()方法,最以后调用相关的业务逻辑中的接收角色

六:UML图

 

   命令模式随处可见,就比如用人关电视这件事,电视黑屏。这其中有几个对象可以抽取出来,

     人--Client

     遥控器--Invoker

     电视机---Receiver

       电视屏幕关掉这个动作----ConcreteCommand

    这其中遥控器(Invoker)和电视机(Receiver)并没有什么交集。他们就是松耦合的关系。

    只是遥控器(Invoker)按了一个关机按钮(相当于发出了一个关机的命令(Command)),至于电视关没有关掉,都和遥控器没关系,因为遥控器只是一个发送命令的。

七:案例源码

行为实现者:

public class TV {
    public void turnOff(){
        System.out.println("TV Close");
    }
    
    public void turnOn(){
        System.out.println("TV trun On");
    }
}
View Code

命令接口:

public interface ICommand {

    void execute();
    
    void redo();
    
    void undo();
}
View Code

 命令实现:

public class TVCommand implements ICommand {

    private TV receiver;
    public TVCommand(TV receiver){
        this.receiver=receiver;
    }
    @Override
    public void execute() {
        this.receiver.turnOn();
    }

    @Override
    public void redo() {
        execute();

    }
    @Override
    public void undo() {
        this.receiver.turnOff();

    }

}
View Code

行为请求者:

import java.util.ArrayList;
import java.util.List;

public class Invoker {

    private List<ICommand> command=new ArrayList<ICommand>();
    
    public Invoker(){
        
    }
    public void storeAndExecute(ICommand cmd){
        if(!command.contains(cmd)){
            this.command.add(cmd);
        }
        cmd.execute();
    }
    
}
View Code

Client:

public class Client {

    public static void main(String[] args) throws Exception {
        Invoker invoker =new Invoker();
        ICommand command=new TVCommand(new TV());
        invoker.storeAndExecute(command);
    }
}
View Code

 

八:总结

  1,命令模式解决了“行为请求者”与“行为实现者”之间紧密耦合的问题,

  2,日志记录,命令撤销,批处理,事务支持都是它带来的好处。,

 综合网上资料和书籍资料加上个人理解所得。请指正。随时更新

posted @ 2014-04-03 13:50  oyaimj  阅读(273)  评论(0)    收藏  举报