命令模式
命令模式
命令模式(Command Pattern)属于行为型模式。它是将一个请求以命令的形式包裹在对象中,并传给调用对象。调用对象寻找可以处理该命令的合适的对象,并把该命令传给相应的对象,该对象执行命令。
它是对命令的封装,每一个命令都是一个操作:请求的一方发出请求要求执行一个操作;接收的一方收到请求,并执行操作。
命令模式通过为请求与实现间引入一个抽象命令接口,解耦请求与实现,并且中间件是抽象的,它可以有不同的子类实现,因此其具备扩展性。所以,命令模式的本质是解耦命令请求与处理。
应用场景
当系统的某项操作具备命令语义时,且命令实现不稳定,那么可以通过命令模式解耦请求与实现,利用抽象命令接口使请求方代码架构稳定,封装接收方具体命令实现细节。接收方与抽象命令接口呈现弱耦合,具备良好的扩展性。
适用场景:
1、只要认为是命令的地方都可以使用命令模式
2、请求调用者和请求的接收者需要解耦,使得调用者和接收者不直接交互
3、需要抽象出等待执行的行为,比如播放操作、暂定操作等
4、需要支持命令宏,即命令组合操作
生活中的应用场景比如:遥控器,播放器,点餐系统。
优缺点
优点:
1.通过引入中间件(抽象接口),解耦了命令请求与实现。
2.扩展性良好,可以很容易地增加新命令。
3.支持组合命令,支持命令队列。
4.可以在现有命令的基础上,增加额外功能。
缺点:
1.具体命令类可能过多。
2.命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构,解耦请求与实现,引入了额外类型结构,增加了理解上的困难
主要角色
1.接收者角色(Receiver)
该类负责具体实施或执行一个请求。
2.命令角色(Command)
定义需要执行的所有命令行为。它作为接收者角色和请求者角色的中间件,解耦彼此。
3.具体命令角色ConcreteCommand)
该类内部维护一个接收者Receiver,在其execute()方法中调用接收者Receiver的相关方法。
4.请求者角色(Invoker)
接收客户端的命令,并执行命令。
命令模式的基本使用
创建接收者角色
接收者角色负责具体实施或执行一个请求。
public class Receiver {
public void action() {
System.out.println("接收者Receiver执行action操作");
}
}
创建命令角色
命令角色定义需要执行的所有命令行为,它作为接收者角色和请求者角色的中间件,解耦彼此。
public interface ICommand {
void execute();
}
具体命令角色
具体命令角色内部维护一个接收者Receiver,在其execute()方法中调用接收者Receiver的相关方法。
public class ConcreteCommand implements ICommand {
// 直接创建接收者,不暴露给客户端
private Receiver mReceiver = new Receiver();
public void execute() {
this.mReceiver.action();
}
}
请求者角色
请求者角色接收客户端的命令,并执行命令。
public class Invoker {
private ICommand mCmd;
public Invoker(ICommand cmd) {
this.mCmd = cmd;
}
public void action() {
this.mCmd.execute();
}
}
客户端执行
public static void main(String[] args) {
ICommand cmd = new ConcreteCommand();
Invoker invoker = new Invoker(cmd);
invoker.action();
}
接收者Receiver执行action操作
命令模式实现播放器功能
创建接收者角色
public class Player {
public void play(){
System.out.println("执行播放操作");
}
public void stop(){
System.out.println("执行暂停播放操作");
}
}
创建命令角色
public interface IAction {
void execute();
}
具体命令角色
创建播放器可以接受的播放指令
public class PlayAction implements IAction {
// 直接创建接收者,不暴露给客户端
private Player player;
public PlayAction(Player player) {
this.player = player;
}
public void execute() {
player.play();
}
}
创建播放器可以接受的暂停指令
public class StopAction implements IAction {
private Player player;
public StopAction(Player player) {
this.player = player;
}
public void execute() {
player.stop();
}
}
创建请求者角色
创建控制器,类似控制面板,执行上面提供的功能即可。如此控制器就与播放器进行解耦了,如新增指令则执行新增命令即可,无需修改控制器。
public class Controller {
private List<IAction> actions = new ArrayList<IAction>();
public void addAction(IAction action) {
actions.add(action);
}
public void execute(IAction action) {
action.execute();
}
public void executes() {
for (IAction action : actions) {
action.execute();
}
actions.clear();
}
}
客户端执行
public static void main(String[] args) {
// 创建一个播放器
Player player = new Player();
Controller controller = new Controller();
// 单个命令执行
controller.execute(new StopAction(player));
System.out.println("------------------");
// 批量执行命令
controller.execute(new PlayAction(player));
controller.addAction(new StopAction(player));
controller.executes();
}
执行暂停播放操作
------------------
执行播放操作
执行暂停播放操作
版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。
文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/136889.html