上一篇:设计模式(十三)——责任链模式
下一篇:设计模式(十五)——中介者模式
一、概述
官方解释:Encapsulate a request as an object,thereby letting you parameterize clients with different requests,queue or log requests, and support undoable operations.(将一个请求封装成一个对象,从而让你使用不同的请求把客户端参数化,对请求排队或者记录请求日志,可以提供命令的撤销和恢复功能。)
我的理解:将命令类Command引用注入到发送者类Invoker中,将接收者Receiver注入到命令类Command中,通过命令类Command作为中间类将发送者Invoker和接收者Receiver解耦。
参与者:发送者Invoker、接收者Receiver、命令类(抽象命令类AbstractCommand、具体命令类ConcreteCommand1、ConcreteCommand2)
类图:
二、代码
代码1(单纯的命令模式结构):
package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Command command=new ConcreteCommand(); command.setReceiver(new Receiver()); Invoker invoker=new Invoker(command); invoker.call(); } } class Invoker{ private Command command; public Invoker(Command command){ this.command=command; } public void setCommand(Command command){ this.command=command; } public void call(){ command.execute(); } } class Receiver{ public void action(){ System.out.println("Receiver action"); } } abstract class Command{ protected Receiver receiver; public void setReceiver(Receiver receiver) { this.receiver = receiver; } public abstract void execute(); } class ConcreteCommand extends Command{ @Override public void execute() { receiver.action(); } }输出:
Receiver action代码2——窗体命令实例:
package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Command command=new WindowCommand(); command.setReceiver(new WindowReceiver()); WindowInvoker invoker=new WindowInvoker(command); invoker.min(); } } class WindowInvoker{ private Command command; public WindowInvoker(Command command){ this.command=command; } public void setCommand(Command command){ this.command=command; } public void min(){ command.min(); } } class WindowReceiver{ public void min(){ System.out.println("窗体最小化到托盘"); } } abstract class Command{ protected WindowReceiver receiver; public void setReceiver(WindowReceiver receiver) { this.receiver = receiver; } public abstract void min(); } class WindowCommand extends Command{ @Override public void min() { receiver.min(); } }输出:
窗体最小化到托盘代码3——窗体命令实例(命令类中方法扩展):
package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Command command=new WindowCommand(); command.setReceiver(new WindowReceiver()); WindowInvoker invoker=new WindowInvoker(command); invoker.min(); invoker.max(); invoker.close(); } } class WindowInvoker{ private Command command; public WindowInvoker(Command command){ this.command=command; } public void setCommand(Command command){ this.command=command; } public void min(){ command.min(); } public void max(){ command.max(); } public void close(){ command.close(); } } class WindowReceiver{ public void min(){ System.out.println("窗体最小化到托盘"); } public void max(){ System.out.println("窗体最大化到屏幕"); } public void close(){ System.out.println("窗体关闭"); } } abstract class Command{ protected WindowReceiver receiver; public void setReceiver(WindowReceiver receiver) { this.receiver = receiver; } public abstract void min(); public abstract void max(); public abstract void close(); } class WindowCommand extends Command{ @Override public void min() { receiver.min(); } @Override public void max() { receiver.max(); } @Override public void close() { receiver.close(); } }输出:
窗体最小化到托盘 窗体最大化到屏幕 窗体关闭代码4——代码3的优化,便于后面扩展:
package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Command command=new WindowCommand(); command.setReceiver(new WindowReceiver()); WindowInvoker invoker=new WindowInvoker(command); invoker.call("min"); invoker.call("max"); invoker.call("close"); } } class WindowInvoker{ private Command command; public WindowInvoker(Command command){ this.command=command; } public void setCommand(Command command){ this.command=command; } public void call(String key){ command.execute(key); } } class WindowReceiver{ public void min(){ System.out.println("窗体最小化到托盘"); } public void max(){ System.out.println("窗体最大化到屏幕"); } public void close(){ System.out.println("窗体关闭"); } } abstract class Command{ protected WindowReceiver receiver; public void setReceiver(WindowReceiver receiver) { this.receiver = receiver; } public abstract void execute(String key); } class WindowCommand extends Command{ public void execute(String key){ switch (key) { case "min": receiver.min(); break; case "max": receiver.max(); break; case "close": receiver.close(); break; default: break; } } }输出:
窗体最小化到托盘 窗体最大化到屏幕 窗体关闭代码5——扩展一个ConcreteCommand:
package mypackage; public class DesignPatternDemo { public static void main(String[] args) { Command command=new WindowCommand(); command.setReceiver(new WindowReceiver()); Invoker invoker=new Invoker(command); invoker.call("min"); invoker.call("max"); invoker.call("close"); command=new MenuCommand(); command.setMenuReceiver(new MenuReceiver()); invoker=new Invoker(command); invoker.call("menuOpen"); invoker.call("menuClose"); } } class Invoker{ private Command command; public Invoker(Command command){ this.command=command; } public void setCommand(Command command){ this.command=command; } public void call(String key){ command.execute(key); } } class WindowReceiver{ public void min(){ System.out.println("窗体最小化到托盘"); } public void max(){ System.out.println("窗体最大化到屏幕"); } public void close(){ System.out.println("窗体关闭"); } } class MenuReceiver{ public void menuOpen(){ System.out.println("菜单打开"); } public void menuClose(){ System.out.println("菜单关闭"); } } abstract class Command{ protected WindowReceiver receiver; protected MenuReceiver menuReceiver; public void setReceiver(WindowReceiver windowReceiver) { this.receiver = windowReceiver; } public void setMenuReceiver (MenuReceiver menuReceiver){ this.menuReceiver=menuReceiver; } public abstract void execute(String key); } class WindowCommand extends Command{ public void execute(String key){ switch (key) { case "min": receiver.min(); break; case "max": receiver.max(); break; case "close": receiver.close(); break; default: break; } } } class MenuCommand extends Command{ public void execute(String key){ switch (key) { case "menuOpen": menuReceiver.menuOpen(); break; case "menuClose": menuReceiver.menuClose(); break; default: break; } } }输出5:
窗体最小化到托盘 窗体最大化到屏幕 窗体关闭 菜单打开 菜单关闭三、小结
设计模式只重其意不重其行,上面5段代码:
第一段介绍命令模式的代码形式;
第二段结合窗体命令;
第三段在ConcreteCommand具体命令类中扩展了max close方法;
第四段代码对第三段代码优化,为第五段代码添加MenuCommand准备;
第五段代码添加另一个具体命令类。
其实整个都是一个换汤不换药的东西,读者理解了命令模式的架构就好,都可以举一反三。
上一篇:设计模式(十三)——责任链模式
下一篇:设计模式(十五)——中介者模式