《设计模式》设计模式的基本原则
《设计模式》单例模式
《设计模式》工厂模式
《设计模式》原型模式
《设计模式》建造者模式
《设计模式》适配器模式
《设计模式》桥接模式
《设计模式》装饰者模式
《设计模式》组合模式
《设计模式》外观模式
《设计模式》享元模式
《设计模式》代理模式
《设计模式》模板方法模式
《设计模式》命令模式
定义:
命令模式的优缺点:
命令模式的使用场景:
命令模式的角色组成:
命令模式的原理类图如下所示:

案例背景:
生活中有这样一个场景:我们去饭店吃饭的时候,服务员先把菜单拿给我们,我们在选好菜之后,再将菜单交给服务员,然后由服务员将菜单告知后厨备菜。其实,在这样的场景中,也可以看成是命令模式的应用。服务员作为命令的调用者 Invoker,负责命令厨师备菜,厨师此时就是命令的接收者 Receiver,具体的命令就是顾客的订单 OrderCommand.
关系类图如下所示:

Command 接口:
public interface Command {void execute();void undo();
}
OrderCommand 类:
public class OrderCommand implements Command{private Chef receiver;private Order order;public OrderCommand(Chef receiver, Order order) {this.receiver = receiver;this.order = order;}@Overridepublic void execute() {System.out.println("-------------------------");System.out.println(order.getDiningTable() + "桌的订单:");Set keys = order.getFoodDic().keySet();for (String key : keys) {receiver.makeFood(order.getFoodDic().get(key), key);}try {// 停顿一下模拟做饭的过程Thread.sleep(100);} catch (InterruptedException e) {e.printStackTrace();Thread.currentThread().interrupt();}System.out.println(order.getDiningTable() + "桌的饭弄好了");}@Overridepublic void undo() {System.out.println("--------------------------");StringBuilder cancel = new StringBuilder();cancel.append(order.getDiningTable()).append("桌的订单:");Set keys = order.getFoodDic().keySet();for (String key : keys) {cancel.append(order.getFoodDic().get(key)).append("份").append(key);}receiver.cancelMakeFood(cancel.toString());}
}
Order 类:
public class Order {private int diningTable;private Map foodDic = new HashMap<>();public int getDiningTable() {return diningTable;}public void setDiningTable(int diningTable) {this.diningTable = diningTable;}public Map getFoodDic() {return foodDic;}public void setFoodDic(String name, Integer num) {foodDic.put(name, num);}
}
Chef 类:
public class Chef {public void makeFood(int num, String foodName) {System.out.println(num + "份" + foodName);}public void cancelMakeFood(String orderName) {System.out.println("取消" + orderName);}
}
Waitor 类:
public class Waitor {private List commands;private List undoCommands;public Waitor() {commands = new ArrayList<>();undoCommands = new ArrayList<>();}public void setCommand(Command cmd){commands.add(cmd);}public void setUndoCommands(Command cmd) {undoCommands.add(cmd);}public void orderUp() {System.out.println("服务员:叮咚,大厨,新订单来了.......");for (int i = 0; i < commands.size(); i++) {Command cmd = commands.get(i);if (cmd != null) {cmd.execute();}}}public void cancelOrder() {for (int i = 0; i < undoCommands.size(); i++) {Command undoCmd = undoCommands.get(i);if (undoCmd != null) {undoCmd.undo();}}}
}
Client 类:
public class Client {public static void main(String[] args) {// 创建两个订单Order order1 = new Order();order1.setDiningTable(1);order1.setFoodDic("西红柿鸡蛋面", 1);order1.setFoodDic("小杯可乐", 1);Order order2 = new Order();order2.setDiningTable(2);order2.setFoodDic("红烧排骨", 2);order2.setFoodDic("柠檬水", 2);// 创建接收者Chef receiver = new Chef();// 将订单和接收者封装成命令对象OrderCommand cmd1 = new OrderCommand(receiver, order1);OrderCommand cmd2 = new OrderCommand(receiver, order2);// 创建调用者 waitorWaitor invoker = new Waitor();invoker.setCommand(cmd1);invoker.setCommand(cmd2);// 撤销订单的命令invoker.setUndoCommands(cmd2);invoker.orderUp();invoker.cancelOrder();}
}
命令模式在 Spring 框架中的 JdbcTemplate 源码中的应用:
query 方法中的返回值类型 StatementCallback 就是一个命令接口 Command.QueryStatementCallback 就是一个具体的命令类同时也是命令接收者,实现了 doInStatement 方法JdbcTemplate 类,在 execute 方法中调用了命令接口的 doInStatement 方法StatementCallback 接口:
public interface StatementCallback {@NullableT doInStatement(Statement var1) throws SQLException, DataAccessException;
}
JdbcTemplate 类:
public class JdbcTemplate extends JdbcAccessor implements JdbcOperations {// ...@Nullablepublic T query(final String sql, final ResultSetExtractor rse) throws DataAccessException {Assert.notNull(sql, "SQL must not be null");Assert.notNull(rse, "ResultSetExtractor must not be null");if (this.logger.isDebugEnabled()) {this.logger.debug("Executing SQL query [" + sql + "]");}class QueryStatementCallback implements StatementCallback, SqlProvider {QueryStatementCallback() {}@Nullablepublic T doInStatement(Statement stmt) throws SQLException {ResultSet rs = null;Object var3;try {rs = stmt.executeQuery(sql);var3 = rse.extractData(rs);} finally {JdbcUtils.closeResultSet(rs);}return var3;}public String getSql() {return sql;}}return this.execute((StatementCallback)(new QueryStatementCallback()));}@Nullablepublic T execute(StatementCallback action) throws DataAccessException {Assert.notNull(action, "Callback object must not be null");Connection con = DataSourceUtils.getConnection(this.obtainDataSource());Statement stmt = null;Object var11;try {stmt = con.createStatement();this.applyStatementSettings(stmt);T result = action.doInStatement(stmt);this.handleWarnings(stmt);var11 = result;} catch (SQLException var9) {String sql = getSql(action);JdbcUtils.closeStatement(stmt);stmt = null;DataSourceUtils.releaseConnection(con, this.getDataSource());con = null;throw this.translateException("StatementCallback", sql, var9);} finally {JdbcUtils.closeStatement(stmt);DataSourceUtils.releaseConnection(con, this.getDataSource());}return var11;}
}
上一篇:【十分钟学懂Linux操作系统】
下一篇:html5+css3