zoukankan      html  css  js  c++  java
  • 命令模式(Command)

    @@@模式定义:
    将一个请求封装为一个对象,从而使你可以用不同的请求对客户进行参数化,
    对请求排队或记录请求日志,以及支持可撤销的操作。


    @@@练习示例: 
    电脑开机


    @@@示例代码:
    patternMainBoardApi.java

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 主板的接口
     */
    public interface MainBoardApi {
        /**
         * 主板具有能开机的功能
         */
    	public void open();
    	
    	/**
    	 * 主板具有实现重启的功能
    	 */
    	public void reset();
    }


    patternGigaMainBoard.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 技嘉主板类,开机命令的真正实现者,在Command模式中充当Receiver
     */
    public class GigaMainBoard implements MainBoardApi {
        /**
         * 真正的开机命令的实现
         */
    	public void open() {
            System.out.println("技嘉主板现在正在开机,请等候");
            System.out.println("接通电源……");
            System.out.println("设备检查……");
            System.out.println("装载系统……");
            System.out.println("机器正常运转起来……");
            System.out.println("机器已经正常打开,请操作");
    	}
    	
    	/**
    	 * 真正的重新启动机器命令的实现
    	 */
    	public void reset() {
    		System.out.println("技嘉主板现在正在重启机器,请等候");
    		System.out.println("机器已经正常打开,请操作");
    	}
    }


    patternCommand.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 命令接口,申明执行的操作
     */
    public interface Command {
        /**
         * 执行命令对应的操作
         */
    	public void execute();
    }


    patternOpenCommand.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 开机命令的实现,实现Command接口
     * 持有开机命令的真正实现,通过调用接收者的方法来实现命令
     */
    public class OpenCommand implements Command {
        /**
         * 持有真正实现命令的接收者——主板对象
         */
    	private MainBoardApi mainBoard = null;
    	
    	/**
    	 * 构造方法,传入主板对象
    	 * @param mainBoard 主板对象
    	 */
    	public OpenCommand(MainBoardApi mainBoard) {
    		this.mainBoard = mainBoard;
    	}
    	
    	@Override
    	public void execute() {
    		// 对于命令对象,根本不知道如何开机,会转调主板对象
            // 让主板去完成开机的功能
    		this.mainBoard.open();
    	}
    }


    patternResetCommand.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 重启机器命令的实现,实现Command接口
     * 持有重启机器命令的真正实现,通过调用接收者的方法来实现命令
     */
    public class ResetCommand implements Command {
    	  /**
         * 持有真正实现命令的接收者——主板对象
         */
    	private MainBoardApi mainBoard = null;
    	
    	/**
    	 * 构造方法,传入主板对象
    	 * @param mainBoard 主板对象
    	 */
    	public ResetCommand(MainBoardApi mainBoard) {
    		this.mainBoard = mainBoard;
    	}
    	
    	@Override
    	public void execute() {
    		// 对于命令对象,根本不知道如何开机,会转调主板对象
            // 让主板去完成重启机器的功能
    		this.mainBoard.reset();
    	}
    }


    patternBox.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    /**
     * 机箱对象,本身有按钮,持有按钮对应的命令对象
     */
    public class Box {
        /**
         * 开机命令对象
         */
    	private Command openCommand;
    	
    	/**
    	 * 设置开机命令对象
    	 * @param command 开机命令对象
    	 */
    	public void setOpenCommand(Command command) {
    		this.openCommand = command;
    	}
    	
    	/**
    	 * 提供给客户使用,接收并响应用户请求,相当于开机按钮被按下触发的方法
    	 */
    	public void openButtonPressed() {
    		// 按下按钮,执行命令
    		openCommand.execute();
    	}
    	
    	private Command resetCommand;
    	
    	/**
    	 * 设置重启机器命令对象
    	 * @param command
    	 */
    	public void setResetCommand(Command command) {
    		this.resetCommand = command;
    	}
    	
    	/**
    	 * 提供给客户使用,接收并响应用户请求,相当于重启按钮被按下触发的方法
    	 */
    	public void resetButtonPressed() {
    		// 按下按钮,执行命令
    		resetCommand.execute();
    	}
    }


    patternClient.java
    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    package pattern;
    
    public class Client {
        public static void main(String[] args) {
        	// 1: 把命令和真正的实现组合起来,相当于在组装机器
        	// 把机箱上按钮的连接线插接到主板上
        	MainBoardApi mainBoard    = new GigaMainBoard();
        	// 创建开机命令
        	OpenCommand  openCommand  = new OpenCommand(mainBoard);
        	// 创建重启命令
        	ResetCommand resetCommand = new ResetCommand(mainBoard);
        	
        	// 2: 为机箱上的按钮设置对应的命令,让按钮知道该干什么
        	Box box = new Box();
        	// 先正确配置,就是开机按钮对开机命令,重启按钮对重启命令
        	box.setOpenCommand(openCommand);
        	box.setResetCommand(resetCommand);
        	
        	// 3: 然后模拟按下机箱上的按钮
        	System.out.println("正确配置下------------------>");
        	System.out.println(">>>按下开机按钮:>>>");
        	box.openButtonPressed();
        	System.out.println(">>>按下重启按钮:>>>");
        	box.resetButtonPressed();
        	
        	// 然后来错误配置一回,反正是进行参数化配置
        	// 就是开机按钮对重启命令,重启按钮对开机命令
        	box.setOpenCommand(resetCommand);
        	box.setResetCommand(openCommand);
        	System.out.println("错误配置下------------------>");
        	System.out.println(">>>按下开机按钮:>>>");
        	box.openButtonPressed();
        	System.out.println(">>>按下重启按钮:>>>");
        	box.resetButtonPressed();
        }
    }


    @@@模式的实现:
    1) 命令模式的关键之处就是把请求封装成为对象,也就是命令对象,并定义了一个统一操作的接口;
    2) 可实现成参数化的命令模式;
    3) 可实现(补偿式/反操作式)可撤销的操作;
    4) 可实现宏命令(命令集);
    5) 可实现队列请求;
    6) 可实现日志请求;


    @@@模式的优点:
    1) 更松散的耦合;
    2) 更动态的控制;
    3) 很自然的复合命令;
    4) 更好地扩展性;


    @@@模式的缺点:
    NA


    @@@模式的本质:
    封装请求


    @@@模式体现的设计原则:
    NA


  • 相关阅读:
    209. Minimum Size Subarray Sum
    208. Implement Trie (Prefix Tree)
    207. Course Schedule
    206. Reverse Linked List
    205. Isomorphic Strings
    204. Count Primes
    203. Remove Linked List Elements
    201. Bitwise AND of Numbers Range
    199. Binary Tree Right Side View
    ArcGIS API for JavaScript 4.2学习笔记[8] 2D与3D视图同步
  • 原文地址:https://www.cnblogs.com/snake-hand/p/3190242.html
Copyright © 2011-2022 走看看