设计模式-命令模式

来源:互联网 发布:mac mail qq邮箱设置 编辑:程序博客网 时间:2024/05/21 20:50

命令模式介绍

        命令模式(Command Pattern),是行为模式之一。命令模式相对于其他设计模式,没有严格的条框,从而显得灵活多变。在实际生活中,我们碰到很多命令模式,比如手机的中有菜单命令,在点击“关机”命令后,系统会执行一系列的操作,如暂停处理的操作,保存相应的系统设置,关闭掉打开的程序等。对于这一系列的操作,用户不用管,系统会自动执行。命令模式就是如此一辙,将一系列的方法调用封装,用户只需要调用一个方法执行,那么所有这些封装的方法就会挨个执行调用。
命令模式的定义

        将一个请求封装成一个对象,从而让用户使用不同的请求客户端参数化;对请求排队或者记录请求日志,以及支持可撤销的操作。

命令模式的使用场景

        需要抽象出待执行的动作,然后以参数的形式提供出来--类似于过程涉及中的回调机制,而命令模式正是回调机制的一个面向对象的替代品。
        在不同的时刻指定、排列和执行请求,一个命令对象可以有与初始请求无关的生存期。
        需要支持取消操作。
        支持修改日志功能,这样当系统崩溃时,这些修改可以被重做一遍。
        需要支持事务操作。

命令模式的UML类图


具体实现

创建接受者角色

public class Music {    /**     * 真正的逻辑操作  - 播放     */    public void play() {        System.out.println("play");    }    /**     * 真正的逻辑操作  - 暂停     */    public void pause() {        System.out.println("pause");    }    /**     * 真正的逻辑操作  - 下一首     */    public void next() {        System.out.println("next");    }    /**     * 真正的逻辑操作  - 上一首     */    public void previous() {        System.out.println("previous");    }}

创建命令角色

public interface Command {    /**     * 命令执行方法     */    void execute();}

创建具体命令角色

/** * 播放命令类 * @Author teaphy * @Date 2016/8/18 */public class PlayCommand implements Command {    // 持有音乐播放器的对象    private Music mMusic;    public PlayCommand(Music music) {        this.mMusic = music;    }    /**     * 命令执行方法     */    public void execute() {        // 调用音乐播放器的具体操作 - 播放        mMusic.play();    }}/** * 暂停命令类 * @Author teaphy * @Date 2016/8/18 */public class PauseCommand implements Command {    // 持有音乐播放器的对象    private Music mMusic;    public PauseCommand(Music music) {        this.mMusic = music;    }    /**     * 命令执行方法     */    public void execute() {        // 调用音乐播放器的具体操作 - 暂停        mMusic.pause();    }}/** * 下一首命令类 * @Author teaphy * @Date 2016/8/18 */public class NextCommand implements Command {    // 持有音乐播放器的对象    private Music mMusic;    public NextCommand(Music music) {        this.mMusic = music;    }    /**     * 命令执行方法     */    public void execute() {        // 调用音乐播放器的具体操作 - 下一首        mMusic.next();    }}/** *  上一首命令类 * @Author teaphy * @Date 2016/8/18 */public class PreviousCommand implements Command {    // 持有音乐播放器的对象    private Music mMusic;    public PreviousCommand(Music music) {        this.mMusic = music;    }    /**     * 命令执行方法     */    public void execute() {        // 调用音乐播放器的具体操作 - 上一首        mMusic.previous();    }}

创建请求者角色

/** * 请求者角色 * @Author teaphy * @Date 2016/8/18 */public class Invoker {    PlayCommand playCommand;    PauseCommand pauseCommand;    NextCommand nextCommand;    PreviousCommand previousCommand;    /**     * 操作  - 暂停     */    public void play() {        pauseCommand.execute();    }    /**     * 操作  - 暂停     */    public void pause() {        pauseCommand.execute();    }    /**     * 操作  - 下一首     */    public void next() {        nextCommand.execute();    }    /**     * 操作  - 上一首     */    public void previous() {        previousCommand.execute();    }    public PlayCommand getPlayCommand() {        return playCommand;    }    public void setPlayCommand(PlayCommand playCommand) {        this.playCommand = playCommand;    }    public PauseCommand getPauseCommand() {        return pauseCommand;    }    public void setPauseCommand(PauseCommand pauseCommand) {        this.pauseCommand = pauseCommand;    }    public NextCommand getNextCommand() {        return nextCommand;    }    public void setNextCommand(NextCommand nextCommand) {        this.nextCommand = nextCommand;    }    public PreviousCommand getPreviousCommand() {        return previousCommand;    }    public void setPreviousCommand(PreviousCommand previousCommand) {        this.previousCommand = previousCommand;    }}</span>

创建操作者角色

<span style="font-size:14px;">public class Listener {    public static void main(String[] args) {        // 创建音乐播放器对象        Music music = new Music();        // 创建执行不同的命令        PlayCommand playCommand = new PlayCommand(music);        PauseCommand pauseCommand = new PauseCommand(music);        NextCommand nextCommand = new NextCommand(music);        PreviousCommand previousCommand = new PreviousCommand(music);        // 设置命令请求者可以执行的命令        Invoker invoker = new Invoker();        invoker.setPlayCommand(playCommand);        invoker.setPauseCommand(pauseCommand);        invoker.setNextCommand(nextCommand);        invoker.setPreviousCommand(previousCommand);        // 根据具体需求执行命令        invoker.play();        invoker.pause();        invoker.next();        invoker.previous();    }}

测试结果

playpausenextprevious

        命令模式将系列操作进行了,逻辑调用十分复杂,但是在实际开发过程中,给我我们带来了十分的便利,例如更改播放的歌曲,只需在Music类中修改该则可,其他操作类不需做出修改。

        同时,在请求者里面,可以记录所有的操作对象,可以方便的知道执行的命令,方便的取消部分操作等,并且可以在需要时回复操作,提高了代码的灵活性。




0 0
原创粉丝点击