命令模式的本质:封装请求
/*
* 命令接口,声明执行的操作
*/
public interface Command {
/**
* 执行命令对应的操作
*/
public void execute();
}
/**
* 开机命令的实现,实现Command接口
* 开机命令的真正实现,通过调用接受者的方法来实现命令
*
*/
public class OpenCommand implements Command {
/**
* 持有真正实现命令的接受者--主板对象
*/
private MainBoardApi mainBoard = null;
/**
* 构造方法,传入主板对象
* @param mainBoard主板对象
*/
public OpenCommand(MainBoardApi mainBoard) {
super();
this.mainBoard = mainBoard;
}
@Override
public void execute() {
// 对于命令对象,根本不知道如何开机,会转调主板对象
//让主板去完成开机的功能
this.mainBoard.open();
}
}
public class ResetCommand implements Command {
private MainBoardApi mainBoard = null;
/**
* 构造方法,传入主板对象
* @param mainBoard主板对象
*/
public ResetCommand(MainBoardApi mainBoard) {
super();
this.mainBoard = mainBoard;
}
@Override
public void execute() {
this.mainBoard.reset();
}
}
/*
* 主板的接口
*/
public interface MainBoardApi {
/**
* 主板具有能开机的功能
*/
public void open();
public void reset();
}
/**
*
* 技嘉主板类,开机命令的真正实现者,在Command模式中充当Receiver
*
*/
public class GigaMainBoard implements MainBoardApi {
@Override
public void open() {
/**
* 真正的开机命令的实现
*/
System.out.println("技嘉主板现在在开机,请等候");
System.out.println("接通电源......");
System.out.println("设备检查......");
System.out.println("装载系统......");
System.out.println("机器正常运转起来......");
System.out.println("机器已经正常打开,请操作");
}
@Override
public void reset() {
System.out.println("技嘉主板现在在重启,请等候");
System.out.println("机器已经正常打开,请操作......");
}
}
/**
*
* 机箱对象,本身有按钮,持有按钮对应的命令对象,在Command模式中充当Invoker
*
*/
public class Box {
/**
* 开机命令对象
*/
private Command openCommand;
/**
* 设置开机命令对象
* @param command开机命令对象
*/
public void setOpenCommand(Command openCommand) {
this.openCommand = openCommand;
}
/**
* 提供给客户使用,接收并相应用户请求,相当于按钮被按下触发的方法
*/
public void openButtonPressed(){
//按下按钮,执行命令
openCommand.execute();
}
private Command resetCommand;
public void setResetCommand(Command resetCommand) {
this.resetCommand = resetCommand;
}
public void resetButtonPressed(){
//按下按钮,执行命令
resetCommand.execute();
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
Box box = assemble();
//然后模拟按下机箱上的按钮
box.openButtonPressed();
box.resetButtonPressed();
}
//应该由工程师来完成这部分工作
private static Box assemble() {
//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);
return box;
}
}
可撤销和恢复的操作:
public interface Command {
public void execute();
public void undo();
}
public class AddCommand implements Command {
private OperationApi operation = null;
private int opeNum;
@Override
public void execute() {
this.operation.add(opeNum);
}
@Override
public void undo() {
this.operation.substract(opeNum);
}
public AddCommand(OperationApi operation, int opeNum) {
super();
this.operation = operation;
this.opeNum = opeNum;
}
}
public class SubstractCommand implements Command {
private OperationApi operation = null;
private int opeNum;
@Override
public void execute() {
this.operation.substract(opeNum);
}
@Override
public void undo() {
this.operation.add(opeNum);
}
public SubstractCommand(OperationApi operation, int opeNum) {
super();
this.operation = operation;
this.opeNum = opeNum;
}
}
/**
*
* 操作运算的接口
*
*/
public interface OperationApi {
/**
* 获得计算完成后的结果
* @return 计算完成后的结果
*/
public int getResult();
/**
* 设置计算开始的初始值
* @return 计算开始的初始值
*/
public void setResult(int result);
/**
* 执行加法
* @param num需要加的数
*/
public void add(int num);
/**
* 执行减法
* @param num需要减的数
*/
public void substract(int num);
}
/**
*
* 运算类,真正实现加减法运算
*
*/
public class Operation implements OperationApi {
private int result;
@Override
public int getResult() {
return result;
}
@Override
public void setResult(int result) {
this.result = result;
}
@Override
public void add(int num) {
result += num;
}
@Override
public void substract(int num) {
result -= num;
}
}
import java.util.ArrayList;
import java.util.List;
public class Cuculator {
private Command addCmd = null;
private Command substractCmd = null;
private List<Command> undoCmds = new ArrayList<Command>();
private List<Command> redoCmds = new ArrayList<Command>();
public void setAddCmd(Command addCmd) {
this.addCmd = addCmd;
}
public void setSubstractCmd(Command substractCmd) {
this.substractCmd = substractCmd;
}
public void addPressed(){
this.addCmd.execute();
undoCmds.add(this.addCmd);
}
public void substractPressed(){
this.substractCmd.execute();
undoCmds.add(this.substractCmd);
}
public void undoPressed(){
if(this.undoCmds.size()>0){
Command cmd = this.undoCmds.get(this.undoCmds.size()-1);
cmd.undo();
redoCmds.add(cmd);
this.undoCmds.remove(cmd);
}else{
System.out.println("很抱歉,没有可撤销的命令");
}
}
public void redoPressed(){
if(this.redoCmds.size()>0){
Command cmd = this.redoCmds.get(this.redoCmds.size()-1);
cmd.execute();
undoCmds.add(cmd);
this.redoCmds.remove(cmd);
}else{
System.out.println("很抱歉,没有可撤销的命令");
}
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
OperationApi operation = new Operation();
AddCommand addCmd = new AddCommand(operation,5);
SubstractCommand substractCmd = new SubstractCommand(operation,3);
Cuculator cuculator = new Cuculator();
cuculator.setAddCmd(addCmd);
cuculator.setSubstractCmd(substractCmd);
cuculator.addPressed();
System.out.println("一次加法运算后的结果为:" + operation.getResult());
cuculator.substractPressed();
System.out.println("一次减法运算后的结果为:" + operation.getResult());
cuculator.undoPressed();
System.out.println("撤销一次后的结果为:" + operation.getResult());
cuculator.undoPressed();
System.out.println("再撤销一次后的结果为:" + operation.getResult());
cuculator.redoPressed();
System.out.println("恢复一次后的结果为:" + operation.getResult());
cuculator.redoPressed();
System.out.println("再恢复一次后的结果为:" + operation.getResult());
}
}
宏命令:
public interface Command {
public void execute();
public void setCookApi(CookApi cookApi);
public int getTableNum();
}
public class ChopCommand implements Command {
private CookApi cookApi = null;
private int tableNum;
public ChopCommand(int tableNum) {
this.tableNum = tableNum;
}
@Override
public void setCookApi(CookApi cookApi) {
this.cookApi = cookApi;
}
@Override
public int getTableNum() {
return tableNum;
}
@Override
public void execute() {
cookApi.cook(tableNum ,"绿豆排骨汤");
}
}
public class DuckCommand implements Command {
private CookApi cookApi = null;
private int tableNum;
public DuckCommand(int tableNum) {
this.tableNum = tableNum;
}
@Override
public void setCookApi(CookApi cookApi) {
this.cookApi = cookApi;
}
@Override
public int getTableNum() {
return tableNum;
}
@Override
public void execute() {
cookApi.cook(tableNum ,"烧鸭");
}
}
public class PorkCommand implements Command {
private CookApi cookApi = null;
private int tableNum;
public PorkCommand(int tableNum) {
this.tableNum = tableNum;
}
@Override
public void setCookApi(CookApi cookApi) {
this.cookApi = cookApi;
}
@Override
public int getTableNum() {
return tableNum;
}
@Override
public void execute() {
cookApi.cook(tableNum ,"凉拌黄瓜");
}
}
import java.util.ArrayList;
import java.util.List;
public class MenuCommand implements Command {
private List<Command> col= new ArrayList<Command>();
public void addCommand(Command command){
col.add(command);
}
@Override
public void execute() {
CommandQueue.addMenu(this);
}
//此实现是没用的
@Override
public int getTableNum() {
return 0;
}
public List<Command> getCommands(){
return this.col;
}
//此实现是没用的
@Override
public void setCookApi(CookApi cookApi) {
}
}
import java.util.ArrayList;
import java.util.List;
public class CommandQueue {
public static List<Command> cmds = new ArrayList<Command>();
public synchronized static void addMenu(MenuCommand menu){
for(Command cmd : menu.getCommands()){
cmds.add(cmd);
}
}
public synchronized static Command getOneCommand(){
Command cmd = null;
if(cmds.size()>0){
cmd = cmds.get(0);
cmds.remove(0);
}
return cmd;
}
}
public interface CookApi {
public void cook(int tableNum,String name);
}
public class HotCook implements CookApi,Runnable {
private String cookerName;
public HotCook(String cookerName) {
this.cookerName = cookerName;
}
@Override
public void cook(int tableNum,String name) {
int cookTime = (int)(20 * Math.random());
System.out.println(this.cookerName + "厨师正在为" + tableNum +"号桌做:"+ name);
try {
Thread.sleep(cookTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.cookerName + "厨师为" + tableNum +"号桌做好了:"+ name + ",共计耗时=" + cookTime + "秒");
}
@Override
public void run() {
while(true){
Command cmd = CommandQueue.getOneCommand();
if(cmd != null){
cmd.setCookApi(this);
cmd.execute();
}
//休息1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class CoolCook implements CookApi,Runnable {
private String cookerName;
public CoolCook(String cookerName) {
this.cookerName = cookerName;
}
@Override
public void cook(int tableNum,String name) {
int cookTime = (int)(20 * Math.random());
System.out.println(this.cookerName + "厨师正在为" + tableNum +"号桌做:"+ name);
try {
Thread.sleep(cookTime);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(this.cookerName + "厨师为" + tableNum +"号桌做好了:"+ name + ",共计耗时=" + cookTime + "秒");
}
@Override
public void run() {
while(true){
Command cmd = CommandQueue.getOneCommand();
if(cmd != null){
cmd.setCookApi(this);
cmd.execute();
}
//休息1s
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
public class CookManager {
private static boolean runFlag = false;
public static void runCookManager(){
if(!runFlag){
runFlag = true;
HotCook cook1 = new HotCook("张三");
HotCook cook2 = new HotCook("李四");
HotCook cook3 = new HotCook("王五");
Thread t1 = new Thread(cook1);
t1.start();
Thread t2 = new Thread(cook2);
t2.start();
Thread t3 = new Thread(cook3);
t3.start();
}
}
}
public class Client {
/**
* @param args
*/
public static void main(String[] args) {
CookManager.runCookManager();
for(int i=1;i<5;i++){
Waiter waiter = new Waiter();
waiter.orderDish(new ChopCommand(i));
waiter.orderDish(new DuckCommand(i));
waiter.orderDish(new PorkCommand(i));
waiter.orderOver();
}
}
}