命令模式
概述
举个现实生活中的例子,开关是请求的发送者,电灯是请求的接收者,它们之间不存在直接的耦合关系,而是通过电线连接到一起,开关不需要知道如何将开灯或关灯请求传输给电灯,而是通过电线来完成这项功能。
可以理解为电线充当封装请求的命令对象,开关如果开则电线通电,并调用电灯的开灯方法,反之则关灯。不同电线可以连接不同的请求接收者,因此只需更换一根电线,相同的开关即可操作不同的电器设备。
在系统中,可以将一个请求封装为一个命令对象,请求发送者通过命令对象发出请求,要求执行一个操作,请求接收者收到请求并执行,用户可以根据需要增加新的命令对象而无须修改原有系统
模式实例
电视机是请求接收者,遥控器是请求发送者,遥控器上有一些不同按钮,对应电视机的不同操作,分别是:打开电视机、关闭电视机和切换频道。
接收者类 Television(电视机类)
public class Televison {
public void open() {
System.out.println("打开电视机");
}
public void close() {
System.out.println("关闭电视机");
}
public void changeChannel() {
System.out.println("切换电视频道");
}
}
抽象命令类 AbstractCommand(命令类)
public interface AbstractCommand {
public void execute();
}
具体命令类 TVOpenCommand(电视机打开命令类)
public class TVOpenCommand implements AbstractCommand {
private Televison tv;
public TVOpenCommand() {
tv = new Televison();
}
@Override
public void execute() {
tv.open();
}
}
具体命令类 TVCloseCommand(电视机关闭命令类)
public class TVCloseCommand implements AbstractCommand {
private Televison tv;
public TVCloseCommand() {
tv = new Televison();
}
@Override
public void execute() {
tv.close();
}
}
具体命令类 TVChangeCommand(电视机频道切换命令类)
public class TVChangeCommand implements AbstractCommand {
private Televison tv;
public TVChangeCommand() {
tv = new Televison();
}
@Override
public void execute() {
tv.changeChannel();
}
}
调用者类 Controller(遥控器类)
public class Controller {
private AbstractCommand openCommand, closeCommand, changeCommand;
public Controller(AbstractCommand openCommand, AbstractCommand closeCommand, AbstractCommand changeCommand) {
this.openCommand = openCommand;
this.closeCommand = closeCommand;
this.changeCommand = changeCommand;
}
public void open() {
openCommand.execute();
}
public void change() {
changeCommand.execute();
}
public void close() {
closeCommand.execute();
}
}
测试类 Client
public class Client {
public static void main(String[] args) {
AbstractCommand openCommand, closeCommand, changeCommand;
openCommand = new TVOpenCommand();
closeCommand = new TVCloseCommand();
changeCommand = new TVChangeCommand();
Controller controller = new Controller(openCommand, closeCommand, changeCommand);
controller.open();
controller.change();
controller.close();
}
}