设计模式(十四)——命令模式

mac2024-10-20  11

上一篇:设计模式(十三)——责任链模式

下一篇:设计模式(十五)——中介者模式

一、概述

官方解释: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准备;

第五段代码添加另一个具体命令类。

其实整个都是一个换汤不换药的东西,读者理解了命令模式的架构就好,都可以举一反三。

 

上一篇:设计模式(十三)——责任链模式

下一篇:设计模式(十五)——中介者模式

最新回复(0)