命令模式(Command)

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


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


@@@示例代码:
\pattern\MainBoardApi.java

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

 

package pattern;

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


\pattern\GigaMainBoard.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("机器已经正常打开,请操作");
	}
}


\pattern\Command.java
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

 

 

package pattern;

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


\pattern\OpenCommand.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();
	}
}


\pattern\ResetCommand.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();
	}
}


\pattern\Box.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();
	}
}


\pattern\Client.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

 


 

posted @ 2013-07-14 23:08  爱生活,爱编程  阅读(323)  评论(0编辑  收藏  举报