設計模式之命令模式

        命令模式是一個高內聚的模式,其定義如下:將一個請求封裝成一個對象,從而讓你使用不同的請求把客戶端參數化,對請求排隊或者記錄日誌,可以提供命令的撤銷和恢復功能。

 

命令模式的通用類圖如下:



 

 

        命令模式是對命令的封裝,命令模式把發出命令的責任和執行命令的責任分開,委派給不同的對象。每一個命令都是這樣一個操作:請求一方發出要求執行一個操作,接收的一方收到請求並執行操作,命令模式允許請求方和執行方獨立。

 

命令模式具有下列特點:

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

這樣我們就可以通過注入的方式將這些類聯繫起來

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章