迭代器模式与命令模式详解(4)

简介: 迭代器模式与命令模式详解(4)

创建命令接口 IAction类:


public interface IAction {
    void execute();
}


然后分别创建操作播放器可以接受的指令,播放指令PlayAction类 :


public class PlayAction implements IAction {
    private GPlayer gplayer;
    public PlayAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }
    public void execute() {
        gplayer.play();
    }
}


暂停指令PauseAction类 :


public class PauseAction implements IAction {
    private GPlayer gplayer;
    public PauseAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }
    public void execute() {
        gplayer.pause();
    }
}


拖动进度条指令SpeedAction类 :


public class SpeedAction implements IAction {
    private GPlayer gplayer;
    public SpeedAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }
    public void execute() {
        gplayer.speed();
    }
}


停止播放指令StopAction类 :


public class StopAction implements IAction {
    private GPlayer gplayer;
    public StopAction(GPlayer gplayer) {
        this.gplayer = gplayer;
    }
    public void execute() {
        gplayer.stop();
    }
}


最后 ,创建控制条Controller类 :


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 class Test {
    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();
    }
}


运行效果如下:


正常播放
暂停播放
正常播放
停止播放
拖动进度条


由于控制条已经与播放器内核解耦了,以后如果想扩展新命令,只需增加命令即可,控制条


的结构无需改动。


七、命令模式在源码中的体现


由于控制条已经与播放器内核解耦了,以后如果想扩展新命令,只需增加命令即可,控制条


的结构无需改动。


public interface Runnable { 
    public abstract void run();
}


实际上调用线程的start()方法之后,就有资格去抢CPU资源,而不需要我们自己编写获得 CPU资源的逻辑。而线程抢到CPU资源后,就会执行run()方法中的内容,用 Runnable接口 把用户请求和CPU执行进行了解耦。


然 后 ,再看一个大家非常孰悉的junit.framework.Test接口 :


package junit.framework; 
public interface Test { 
    public abstract int countTestCases(); 
    public abstract void run(TestResult result);
}


Test接口中有两个方法,第一个是countTestCases()方法用来统计当前需要执行的测试用例 总数。第二个是run()方法就是用来执行具体的测试逻辑,其参数TestResult是用来返回测试结果的。 实际上我们在平时编写测试用例的时候,只需要实现Test接口即便认为就是一个测试用例,那 么在执行的时候就会自动识别。实际上我们平时通常做法都是继承TestCase类 ,我们不妨来看

—下 TestCase的源码:


public abstract class TestCase extends Assert implements Test { 
    ...
    public void run(TestResult result) { 
        result.run(this);
  }
    ...
}


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


八、命令模式的优缺点

优点:


1、通过引入中间件(抽象接口),解耦了命令请求与实现;


2、 扩展性良好,可以很容易地增加新命令;


3、 支持组合命令,支持命令队列;


4、可以在现有命令的基础上,增加额外功能(比如日志记录…,结合装饰器模式更酸爽)。


缺点:


1、 具体命令类可能过多;


2、 命令模式的结果其实就是接收方的执行结果,但是为了以命令的形式进行架构,解耦请求与

实现,引入了额外类型结构(引入了请求方与抽象命令接口),增加了理解上的困难(不过这

也是设计模式带来的一个通病,抽象必然会引入额外类型;抽象肯定比紧密难理解)。


十一、迭代器模式与命令模式详解


目录
相关文章
|
数据采集 供应链 搜索推荐
数据集成:融合不同来源的数据
【6月更文挑战第4天】数据集成在企业中发挥关键作用,连接数据孤岛,促进信息流动,提升决策能力。通过抽取、清洗、转换和加载(ETL)不同来源、格式的数据,整合到统一框架,进行深度分析。以零售商为例,集成销售、客户和供应链数据可优化库存管理。数据清洗确保质量,转换满足分析需求,最终加载到数据仓库。Python和pandas库是实现这一过程的工具之一。随着技术进步,数据集成将推动企业向智能化和个性化发展。
322 2
|
Ubuntu
简单几步实现Ubuntu22.04启用Nvidia显卡
本文是关于如何在Ubuntu 22.04操作系统上启用Nvidia显卡的教程,包括禁用旧驱动、添加新驱动源、安装推荐驱动、重启系统以及通过Nvidia设置更改为高性能模式的步骤。
3015 0
简单几步实现Ubuntu22.04启用Nvidia显卡
|
12月前
|
API Python
Matplotlib 教程 之 Matplotlib Pyplot 1
Matplotlib Pyplot 是 Matplotlib 的一个子库,提供了与 MATLAB 类似的绘图 API。它常用於绘制 2D 图表,包含了一系列可以对当前图像进行修改的函数,如添加标记、生成新图像等。通过 `import matplotlib.pyplot as plt` 导入后,可使用如 `plot()`、`scatter()`、`bar()`、`hist()`、`pie()` 和 `imshow()` 等函数绘制不同类型的图表,并可通过其他函数设置图表属性、添加文本或保存图表。例如,使用 `plot()` 可根据指定坐标绘制线图。
112 5
|
JavaScript 小程序
VUE3(三十五)vite构建的项目配置使用.env文件
VUE3(三十五)vite构建的项目配置使用.env文件如标题所示:我要在vue3项目使用.env文件。 先介绍一下项目背景,项目使用VUE3.2 + vite2.9 + typescript搭建。 我基本断定,vue3使用.env文件的方法可能和vue2使用.env文件的方法可能是不同,关于vue2项目如何使用.env文件,请移步《VUE2(七)VUE配置env文件使用》
628 1
|
SQL 缓存 Java
使用Hibernate实现复杂数据库查询优化策略
使用Hibernate实现复杂数据库查询优化策略
|
消息中间件 NoSQL Java
Redis实现延迟队列,我研究了两种方案,发现并不简单
前段时间有个小项目需要使用延迟任务,谈到延迟任务,我脑子第一时间一闪而过的就是使用消息队列来做,比如RabbitMQ的死信队列又或者RocketMQ的延迟队列,但是奈何这是一个小项目,并没有引入MQ,我也不太想因为一个延迟任务就引入MQ,增加系统复杂度,所以这个方案直接就被pass了。
面向对象和面向过程
面向对象和面向过程
114 0
|
供应链 前端开发 数据管理
基于Springboot+Vue开发前后端端分离农产品进销存系统
农产品进销存系统是针对商店、商场、超市的进销存业务处理的计算机化而设计,为进销存业务的处理人员提供计算机化的服务,改变以往的手工操作,提高工作效率,进而增强竞争力。本系统提供的服务主要有商品的进货、销售、库存管理以及相应的报表、查询功能等。系统使用前后端分离模式开发实现,后台使用springboot+mybatis开发,前端使用vue+nodejs实现,通过接口远程调用。
461 0
基于Springboot+Vue开发前后端端分离农产品进销存系统
|
NoSQL Java Redis
(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
1013 1
(Redis使用系列) Springboot 使用redis的List数据结构实现简单的排队功能场景 九
|
Java Linux
CentOS7系统下安装OpenOffice
CentOS7系统下安装OpenOffice
844 1
CentOS7系统下安装OpenOffice