`

设计模式之命令模式

 
阅读更多

        命令模式是一个高内聚的模式,其定义如下:将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录日志,可以提供命令的撤销和恢复功能。

 

命令模式的通用类图如下:



 

 

        命令模式是对命令的封装,命令模式把发出命令的责任和执行命令的责任分开,委派给不同的对象。每一个命令都是这样一个操作:请求一方发出要求执行一个操作,接收的一方收到请求并执行操作,命令模式允许请求方和执行方独立。

 

命令模式具有下列特点:

1.类见解耦

执行者和接收者之间没有任何依赖关系,调用者实现时只需要调用Command抽象类的execute方法就可以了,不需要知道到底是那个接收者执行。

 

2.扩展性高

Command的子类可以非常容易扩展,而调用者Invoker和高层次的模块Client不产生严重的耦合

 

任何事物都不可能十全十美,命令模式的缺点就是可能会出现类膨胀的情况,就是命令类Command的子类会出现多个的情况

 

通用类图的源码如下:

 

/**
 * 抽象命令类
 * 
 */
public abstract class Command {

    protected abstract void execute();
}

 

/**
 * 命令的具体实现类
 * 
 */
public class ConcreteCommand extends Command {

    private Reciver reciver;

    public ConcreteCommand(Reciver reciver) {

        this.reciver = reciver;
    }

    /**
     * 命令的执行方法
     * 
     * @see com.huashao.chapter.chapter15.ch01.Command#execute()
     */
    @Override
    protected void execute() {

        reciver.action();
    }

}

 

/**
 * 接收者角色
 * 
 */
public class Reciver {

    public void action() {

        System.out.println("保证完成任务");
    }
}

 

public class Invoker {

    private Command command;

    public Invoker(Command command) {

        this.command = command;
    }

    public void action() {

        this.command.execute();
    }
}

 

public class Client {

    public static void main(String[] args) {
        // 创建接收者
        Reciver reciver = new Reciver();
        // 创建命令
        Command command = new ConcreteCommand(reciver);
        // 创建执行者
        Invoker invoker = new Invoker(command);
        // 执行请求
        invoker.action();
    }
}

 

最近在做一个电商结算项目,其中有这么一个功能:整个界面就是一个查询,不过查询的条件有很多种,截图如下:

 



 

看看能不能用命令模式的方式实现(使用命名模式好不好先放在一边),那么我们是不是就可以将每一种查询类型看做一个命令呢

 

类图如下:

 



 

代码如下:

 

/**
 * 命令对象
 * 
 */
public class CommandVO {

    private String command;

    private String value;

    /**
     * 
     */
    public CommandVO() {
        super();
        // TODO Auto-generated constructor stub
    }

    /**
     * @param command
     * @param value
     */
    public CommandVO(String command, String value) {
        super();
        this.command = command;
        this.value = value;
    }

    public String getCommand() {
        return command;
    }

    public void setCommand(String command) {
        this.command = command;
    }

    public String getValue() {
        return value;
    }

    public void setValue(String value) {
        this.value = value;
    }

}

 

public class ResultVO {

    private String sequence;

    private String type;

    public String getSequence() {
        return sequence;
    }

    public void setSequence(String sequence) {
        this.sequence = sequence;
    }

    public String getType() {
        return type;
    }

    public void setType(String type) {
        this.type = type;
    }

    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return "[查询主键:" + sequence + " 交易类型:" + type + "]";
    }

}

 

/**
 * 命令对象的接口
 * 
 */
public interface QueryCommand {

    // 查询方法
    public List<ResultVO> execute(CommandVO commandVO);
}

 

/**
 * 根据票号查询
 * 
 */
public class TktNoQueryCommand implements QueryCommand {

    
    private QueryReciver reciver;

    public TktNoQueryCommand(QueryReciver reciver) {

        this.reciver = reciver;
    }
    
    /**
     * @param commandVO
     * @return
     */
    @Override
    public List<ResultVO> execute(CommandVO commandVO) {
        // TODO Auto-generated method stub
        return reciver.tktNoQuery(commandVO);
    }

}

 

/**
 * 根据订单号查询
 * 
 */
public class OrderNoQueryCommand implements QueryCommand {

    private QueryReciver reciver;

    public OrderNoQueryCommand(QueryReciver reciver) {

        this.reciver = reciver;
    }
    
    /**
     * @param commandVO
     * @return
     */
    @Override
    public List<ResultVO> execute(CommandVO commandVO) {
        // TODO Auto-generated method stub
        return reciver.orderNoQuery(commandVO);
    }

}

 

/**
 * 根据退款订单号查询
 * 
 */
public class RefundNoQueryCommand implements QueryCommand {

    private QueryReciver reciver;

    public RefundNoQueryCommand(QueryReciver reciver) {

        this.reciver = reciver;
    }

    /**
     * @param commandVO
     * @return
     */
    @Override
    public List<ResultVO> execute(CommandVO commandVO) {
        return reciver.refundNoQuery(commandVO);
    }

}

 

/**
 * 查询的接收者
 * 
 */
public class QueryReciver {

    // 根据退款订单号查询
    public List<ResultVO> refundNoQuery(CommandVO commandVO) {
        
        System.out.println(commandVO.getCommand());
        //模拟从数据库获取结果
        List<ResultVO> list=new ArrayList<ResultVO>();
        
        ResultVO vo=new ResultVO();
        
        vo.setSequence(commandVO.getValue());
        vo.setType("RFD");
        list.add(vo);
        return list;

    }

    // 根据票号查询
    public List<ResultVO> tktNoQuery(CommandVO commandVO) {
      
        System.out.println(commandVO.getCommand());
        //模拟从数据库获取结果
        List<ResultVO> list=new ArrayList<ResultVO>();
        
        ResultVO vo=new ResultVO();
        
        vo.setSequence(commandVO.getValue());
        vo.setType("RFD");
        list.add(vo);
        return list;

    }

    // 根据订单号查询
    public List<ResultVO> orderNoQuery(CommandVO commandVO) {
        
        System.out.println(commandVO.getCommand());
        //模拟从数据库获取结果
        List<ResultVO> list=new ArrayList<ResultVO>();
        
        ResultVO vo=new ResultVO();
        
        vo.setSequence(commandVO.getValue());
        vo.setType("SAL");
        list.add(vo);
        return list;

    }
}

 

public class Client {

    public static void main(String[] args) {

        // 创建接收者
        QueryReciver reciver = new QueryReciver();
        // 创建命令对象
        CommandVO vo = new CommandVO("TktNo", "232424");
        // 创建命令
        QueryCommand command = null;

        if ("TktNo".equalsIgnoreCase(vo.getCommand())) {
            command = new TktNoQueryCommand(reciver);
        }

        // 创建执行者
        Invoker invoker = new Invoker();
        invoker.setCommand(command);

       List<ResultVO> list= invoker.query(vo);
       
       for(ResultVO vo2:list){
           System.out.println(vo2);
       }
    }

}

 

因为我们用的Struts2+Spring+Hibernate的模式开始,那么上面的类图如何体现在这几个框架上呢?

Invoker就是相当于我们写的Action类,而Command类就相当于Service 那么Reciver就相当于Dao

这样我们就可以通过注入的方式将这些类联系起来

  • 大小: 22.7 KB
  • 大小: 20.9 KB
  • 大小: 86.7 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics