Java 设计模式之命令模式
一、定义
将一个请求封装为一个对象,使发出请求的责任和执行请求的责任分割开。这样两者之间通过命令对象进行沟通,这样方便将命令对象进行储存、传递、调用、增加与管理。
主要角色:
抽象命令角色:定义命令的接口,声明执行的方法。
具体命令角色:具体的命令,实现命令接口,通常会持有接收者,并调用接收者的功能来完成命令要执行的操作。
接收者角色:接收者,真正执行命令的对象,任何类都可能成为一个接收者,只要它能够实现命令要求实现的相应功能。
请求者角色:要求命令对象执行请求,通常会持有命令对象,可以持有很多的命令对象,这个是客户端真正触发命令并要求命令执行相应操作的地方,就是说相当于使用命令对象的入口。
二、代码实现
举例:比如遥控器控制电视机的打开和关闭,其中通过遥控器发送命令,电视机收到命令并执行相应的操作。
接收者角色:电视
public class Tv { public void onTv(){ System.out.println("打开电视"); } public void offTv(){ System.out.println("关闭电视"); } }
抽象命令角色:
public interface Command { void execute(); }
具体命令角色:打开电视
public class OnTvCommand implements Command{ private Tv tv; public OnTvCommand(Tv tv) { this.tv = tv; } @Override public void execute() { tv.onTv(); } }
具体命令角色:关闭电视
public class OffTvCommand implements Command{ private Tv tv; public OffTvCommand(Tv tv) { this.tv = tv; } @Override public void execute() { tv.offTv(); } }
请求者角色:遥控器
//请求者角色 public class RemoteControl { private Command onTvCommand; private Command offTvCommand; public RemoteControl(Command onTvCommand, Command offTvCommand) { this.onTvCommand = onTvCommand; this.offTvCommand = offTvCommand; } //打开 public void clickOn(){ onTvCommand.execute(); } //关闭 public void clickOff(){ offTvCommand.execute(); } }
使用:
public static void main(String[] args) { //定义电视 Tv tv = new Tv(); //定义具体命令 Command on = new OnTvCommand(tv); Command off = new OffTvCommand(tv); //定义遥控器 RemoteControl remoteControl = new RemoteControl(on,off); //使用遥控器打开电视 remoteControl.clickOn(); //使用遥控器关闭电视 remoteControl.clickOff(); }
输出:
打开电视 关闭电视
三、总结
优点:
1.降低调用者和接收者之间的耦合度。
2.容易添加新的命令到系统中。
3.可以实现宏命令,与组合模式结合,将多个命令装配成一个组合命令。
缺点:
1.使用命令模式可能会导致程序中有过多的具体命令类。
2.会使系统结构更复杂
使用场景:
1.需要将请求调用者和请求接收者解耦时,使调用者和接收者不直接交互。