• 欢迎访问搞代码网站,推荐使用最新版火狐浏览器和Chrome浏览器访问本网站!
  • 如果您觉得本站非常有看点,那么赶紧使用Ctrl+D 收藏搞代码吧

关于java:使用命令模式重构播放器控制条

java 搞代码 3年前 (2022-01-27) 69次浏览 已收录 0个评论
文章目录[隐藏]

本文节选自《设计模式就该这样学》

1 命令模式的UML类图

命令模式的UML类图如下图所示。

2 应用命令模式重构播放器管制条

如果咱们开发一个播放器,播放器有播放性能、拖动进度条性能、进行播放性能、暂停性能,咱们在操作播放器的时候并不是间接调用播放器的办法,而是通过一个管制条去传播指令给播放器内核,具体传播什么指令,会被封装为一个个按钮。那么每个按钮就相当于对一条命令的封装。用管制条实现了用户发送指令与播放器内核接管指令的解耦。上面来看代码,首先创立播放器内核GPlayer类。

<code class="java">
public class GPlayer {

    public void play(){
        System.out.println("失常播放");
    }

    public void speed(){
        System.out.println("拖动进度条");
    }

    public void stop(){
        System.out.println("进行播放");
    }

    public void pause(){
        System.out.println("暂停播放");
    }
        
}

创立命令接口IAction类。

<code class="java">
public interface IAction {

    void execute();
        
}

而后别离创立操作播放器能够接管的指令,播放指令PlayAction类的代码如下。

<code class="java">
public class PlayAction implements IAction {

    private GPlayer gplayer;

    public PlayAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }

    public void execute() {
        gplayer.play();
    }
        
}

暂停指令PauseAction类的代码如下。

<code class="java">
public class PauseAction implements IAction {

    private GPlayer gplayer;

    public PauseAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }

    public void execute() {
        gplayer.pause();
    }
        
}

拖动进度条指令SpeedAction类的代码如下。

<code class="java">
public class SpeedAction implements IAction {

    private GPlayer gplayer;

    public SpeedAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }

    public void execute() {
        gplayer.speed();
    }
        
}

进行播放指令StopAction类的代码如下。

<code class="java">
public class StopAction implements IAction {

    private GPlayer gplayer;

    public StopAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }

    public void execute() {
        gplayer.stop();
    }
}

最初创立管制条Controller类。

<code class="java">
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();
    }
}

从下面代码来看,管制条能够执行单条命令,也能够批量执行多条命令。上面来看客户端测试代码。

<code class="java">
public static void main(String[] args) {

        GPlayer player = new GPlayer();
        Controller controller = new Controller();
        controller.execute(new PlayAction(player));

        controller.addAction(new PauseAction(player));
        controller.addAction(new PlayAction(player));
        controller.addAction(new StopAction(player));
        controller.addAction(new SpeedAction(player));
        controller.executes();
}
        

因为管制条曾经与播放器内核解耦了,当前如果想扩大新命令,只需减少命令即可,管制条的构造毋庸改变。

3 命令模式在JDK源码中的利用

首先来看JDK中的Runnable接口,Runnable相当于命令的形象,只有是实现了Runnable接口的类都被认为是一个线程。

<code class="java">
public interface Runnable {
    public abstract void run();
}

实际上调用线程的start()办法之后,就有资格去抢CPU资源,而不须要编写取得CPU资源的逻辑。而线程抢到CPU资源后,就会执行run()办法中的内容,用Runnable接口把用户申请和CPU执行进行解耦。

4 命令模式在JUnit源码中的利用

再来看一个大家十分相熟的junit.framework.Test接口。

<code class="java">
package junit.framework;

public interface Test {
    public abstract int countTestCases();

    public abstract void run(TestResult result);
}

Test接口中有两个办法,第一个是countTestCases()办法,用来统计以后须要执行的测试用例总数。第二个是run()办法,用来执行具体的测试逻辑,其参数TestResult是用来返回测试后果的。实际上,咱们在平时编写测试用例的时候,只须要实现Test接口就被认为是一个测试用例,那么在执行的时候就会被自动识别。通常做法都是继承TestCase类,无妨来看一下TestCase的源码。

<code class="java">
public abstract class TestCase extends Assert implements Test {
        ...
        public void run(TestResult result) {
        result.run(this);
     }
     ...
}

实际上,TestCase类也实现了Test接口。咱们继承TestCase类,相当于也实现了Test接口,天然就会被扫描成为一个测试用例。


搞代码网(gaodaima.com)提供的所有资源部分来自互联网,如果有侵犯您的版权或其他权益,请说明详细缘由并提供版权或权益证明然后发送到邮箱[email protected],我们会在看到邮件的第一时间内为您处理,或直接联系QQ:872152909。本网站采用BY-NC-SA协议进行授权
转载请注明原文链接:关于java:使用命令模式重构播放器控制条

喜欢 (0)
[搞代码]
分享 (0)
发表我的评论
取消评论

表情 贴图 加粗 删除线 居中 斜体 签到

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址