行为型设计模式之命令模式

生活中,最使人疲惫的往往不是道路的遥远,而是心中的郁闷;最使人痛苦的往往不是生活的不幸,而是希望的破灭;最使人颓废的往往不是前途的坎坷,而是自信的丧失;最使人绝望的往往不是挫折的打击,而是心灵的死亡。所以我们要有自己的梦想,让梦想的星光指引着我们走出落漠,走出惆怅,带着我们走进自己的理想。

导读:本篇文章讲解 行为型设计模式之命令模式,希望对大家有帮助,欢迎收藏,转发!站点地址:www.bmabk.com,来源:原文

命令模式

命令模式(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

(0)
飞熊的头像飞熊bm

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!