前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >Java设计模式之迭代器模式

Java设计模式之迭代器模式

作者头像
CoderJed
发布于 2018-11-09 07:05:07
发布于 2018-11-09 07:05:07
79810
代码可运行
举报
文章被收录于专栏:Jed的技术阶梯Jed的技术阶梯
运行总次数:0
代码可运行

老板让我打印各个项目的报表,包括项目名称,人数,开销等信息,这个好办,看下面的类图:

image.png

然后是上面类图的代码实现,非常简单:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IProject {
    
    String getProjectInfo();

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Project implements IProject {
    
    private String name; // 项目名称
    private int num; // 项目人数
    private int cost; // 项目支出
    
    public Project(String name, int num, int cost) {
        this.name = name;
        this.num = num;
        this.cost = cost;
    }
    
    
    @Override
    public String getProjectInfo() {
        StringBuilder builder = new StringBuilder();
        builder.append("项目名称:").append(name).append(",项目人数:").append(num).append(",项目支出:").append(cost);
        return builder.toString();
    }

}

Boss想查看各项目明细,需要这么做:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Boss {

    public static void main(String[] args) {

        // 定义一个List,存放所有的项目对象
        ArrayList<IProject> projectList = new ArrayList<IProject>();

        // 增加星球大战项目
        projectList.add(new Project("星球大战", 10, 100000));
        // 增加扭转时空项目
        projectList.add(new Project("扭转时空", 100, 1000000));
        // 增加超人改造项目
        projectList.add(new Project("超人改造", 10000, 10000000));
        // 增加100个其他项目
        for (int i = 4; i < 104; i++) {
            projectList.add(new Project("第" + i + "个项目", i * 5, i * 1000000));
        }

        // 遍历ArrayList,把所有项目的信息都取出
        for (IProject project : projectList) {
            System.out.println(project.getProjectInfo());
        }

    }

}

# 运行结果
项目名称:星球大战,项目人数:10,项目支出:100000
项目名称:扭转时空,项目人数:100,项目支出:1000000
项目名称:超人改造,项目人数:10000,项目支出:10000000
项目名称:第4个项目,项目人数:20,项目支出:4000000
......

我开始思考,在这种场景下,使用迭代器模式会更好,于是我修改了类图:

然后根据类图修改了代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IProject {
    
    // 增加项目
    void add(String name, int num, int cost);
    
    // 获得项目信息
    String getProjectInfo();
    
    // 获得一个可以被遍历的对象
    IProjectIterator iterator();

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Project implements IProject {
    
    private List<IProject> projectList = new ArrayList<>(); // 项目列表
    private String name; // 项目名称
    private int num; // 项目人数
    private int cost; // 项目支出
    
    public Project() {}
    
    private Project(String name, int num, int cost) {
        this.name = name;
        this.num = num;
        this.cost = cost;
    }
    
    @Override
    public void add(String name, int num, int cost) {
        this.projectList.add(new Project(name, num, cost));
    }
    
    @Override
    public String getProjectInfo() {
        StringBuilder builder = new StringBuilder();
        builder.append("项目名称:").append(name).append(",项目人数:").append(num).append(",项目支出:").append(cost);
        return builder.toString();
    }

    @Override
    public IProjectIterator iterator() {
        return new ProjectIterator(projectList);
    }

}
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public interface IProjectIterator extends Iterator<IProject> {

}

大家可能很奇怪,你定义的这个接口方法、变量都没有,有什么意义呢?有意义,所有的Java书上都一直说是面向接口编程,你的接口是对一个事物的描述,也就是说我通过接口就知道这个事物有哪些方法,哪些属性,我们这里的IProjectIterator是要建立一个指向Project类的迭代器,目前暂时定义的就是一个通用的迭代器,可能以后会增加IProjectIterator的一些属性或者方法。当然了,你也可以在实现类上实现两个接口,一个是Iterator,一个是IProjectIterator(这时候,这个接口就不用继承Iterator),我的习惯是:如果我要实现一个容器或者其他API提供接口时,我一般都自己先写一个接口继承,然后再继承自己写的接口,保证自己的实现类只用实现自己写的接口(接口传递,当然也要实现顶层的接口),程序阅读也清晰一些,我们继续看迭代器的实现类:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class ProjectIterator implements IProjectIterator {
    
    // 项目列表
    private List<IProject> projectList = new ArrayList<>();
    private int currentItem = 0;
    
    public ProjectIterator(List<IProject> projectList) {
        this.projectList = projectList;
    }

    // 判断是否还有元素
    @Override
    public boolean hasNext() {
        return !(currentItem >= projectList.size() || projectList.get(currentItem) == null);
    }

    // 取下一个值
    @Override
    public IProject next() {
        return projectList.get(currentItem++);
    }

}

然后看看Boss类有多少改动:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
public class Boss {

    public static void main(String[] args) {

        IProject project = new Project();

        // 增加星球大战项目
        project.add("星球大战", 10, 100000);
        // 增加扭转时空项目
        project.add("扭转时空", 100, 1000000);
        // 增加超人改造项目
        project.add("超人改造", 10000, 10000000);
        // 增加100个其他项目
        for (int i = 4; i < 104; i++) {
            project.add("第" + i + "个项目", i * 5, i * 1000000);
        }

        IProjectIterator iterator = project.iterator();
        while(iterator.hasNext()) {
            IProject p = iterator.next();
            System.out.println(p.getProjectInfo());
        }

    }

}

上面的程序增加了复杂性,但是从面向对象的开发上来看,project.add()增加一个项目会更友好一些,上面的例子就使用了迭代器模式。

现在迭代器模式有点没落了,从JDK1.2版本开始增加java.util.Iterator这个接口,并逐步把Iterator应用到各个集合类中,大部分集合类都有iterator()这个方法,我们可以通过这个方法去遍历集合类中的所有方法或属性,不需要自己再去写迭代器,所以基本上很少有项目再独立写迭代器了,直接使用List或者Map就可以完整的解决问题。

本文原书: 《您的设计模式》 作者:CBF4LIFE

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2018.10.23 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
1 条评论
热度
最新
似乎有用
似乎有用
回复回复点赞举报
推荐阅读
编辑精选文章
换一批
markdown语法
Markdown 语法说明 (简体中文版) / (点击查看快速入门) 概述 宗旨 兼容 HTML 特殊字符自动转换 区块元素 段落和换行 标题 区块引用 列表 代码区块 分隔线 区段元素 链接 强调 代码 图片 其它 反斜杠 自动链接 感谢 概述 宗旨 Markdown 的目标是实现「易读易写」。 可读性,无论如何,都是最重要的。一份使用 Markdown 格式撰写的文件应该可以直接以纯文本发布,并且看起来不会像是由许多标签或是格式指令所构成。Markdown 语法受到一些既有 text-to-HTML
lwen
2018/04/17
1K0
Markdown - 让网络书写变得简单
可读性,无论如何,都是最重要的。一份使用 Markdown 格式撰写的文件应该可以直接以纯文本发布,并且看起来不会像是由许多标签或是格式指令所构成。Markdown 语法受到一些既有 text-to-HTML 格式的影响,包括 Setext、atx、Textile、reStructuredText、Grutatext 和 EtText,而最大灵感来源其实是纯文本电子邮件的格式。
laixiangran
2018/07/25
1.3K0
Markdown基础教程
Markdown 换行挺讲究,会发现在编写的时候直接回车换行发现不生效,那怎么办呢?
小城故事
2022/11/30
6.4K0
Markdown 语法说明(简体中文版)
NOTE: This is Simplelified Chinese Edition Document of Markdown Syntax. If you are seeking for English Edition Document. Please refer to Markdown: Syntax. 声明: 这份文档派生(fork)于繁体中文版,在此基础上进行了繁体转简体工作,并进行了适当的润色。此文档用 Markdown 语法编写,你可以到这里查看它的源文件。「繁体中文版的原始文件可以查看这里
_gongluck
2018/03/08
2.4K0
Typora Markdown 语法
当前许多网站都广泛使用 Markdown 来撰写帮助文档或是用于论坛上发表消息。例如:GitHub、简书、reddit、Diaspora、Stack Exchange、OpenStreetMap 、SourceForge等。
框架师
2021/03/08
2.9K0
Typora Markdown 语法
MarkDown简单使用A First Level Header
上面是原始文本,下面是对应Markdown效果,整理出来,方便查阅. A First Level Header ==================== A First Level Header A Second Level Header --------------------- A Second Level Header ### Header 3 Header 3 > This is a blockquote. > > This is the second paragraph in the block
dreamkong
2018/06/21
6010
[MarkDown] MarkDown语法小结
HTML中 < 和 & 都要转码 但markdown不必,输入& 和 &amp; 都显示 &,< 也一样
wOw
2018/09/18
8550
[MarkDown] MarkDown语法小结
十五分钟让你快速学习Markdown语法到精通排版实践
描述: Markdown 是一种轻量级标记语言于2004年推出,创始人为约翰·格鲁伯(John Gruber)。 它允许人们使用易读易写的纯文本格式编写文档,然后转换成有效的 XHTML(或者HTML)文档。
全栈工程师修炼指南
2022/09/29
2.6K0
MarkDown轻量级标记语言
####1.标题 #一级标题 ##二级标题 ###三级标题 … ######六级标题 ####2.引用 >这个是引用 >是不是和电子邮件中的 >引用格式很像 ####3.段落  半方大空格  全方大空格 行末尾加多个空格为分行符 ####4.强调 text或_text_ text或__text__ ***text***或___text___ ####5.列表 - 无序列表1 - 无序列表2 - 无序列表2.1 - 列表内容 - 列表内容
sofu456
2019/07/09
9360
MarkDown轻量级标记语言
markdown 基本语法(转载)
最近感觉一直使用富文本编辑器写东西,感觉有点烦,所以就试着学习了一下简单的markdown编辑器的使用
lin_zone
2018/08/15
4700
markdown 基本语法(转载)
Day1-白雪
1,Markdown支持两种标题的语法,类Setext和类atx形式,前者是利用底线的形式区分不同级别的标题,但是输入较多,不如使用类atx形式,该种是在行首添加1-6个#,对应的是标题1-6阶,此处注意一定要在#后面加上空格再跟相应的内容,否则无法识别。
用户10300557
2023/01/09
6450
Markdown语法图文全面详解(10分钟学会)
博客:https://www.jianshu.com/u/f408bdadacce
陈宇明
2020/12/15
17.9K1
Markdown语法图文全面详解(10分钟学会)
Markdown 语法手册 (完整整理版)
1. 斜体和粗体 代码: *斜体*或_斜体_ **粗体** ***加粗斜体*** ~~删除线~~ 显示效果: 这是一段斜体 这是一段粗体 这是一段加粗斜体 这是一段删除线 2. 分级标题 第一种写法: 这是一个一级标题 ============================ 这是一个二级标题 --------------------------------------------------
似水的流年
2018/01/18
7.3K0
Markdown 语法手册 (完整整理版)
Markdown 语法手册 (完整整理版)
由于用了[TOC]标记编辑器会把所有标题写到目录大纲中,在这里写的演示标题也会列进去,所以就不演示了。同学们自己在编辑器中观察,很简单,一级标题字号最大,依级递减。
似水的流年
2019/12/13
1.2K0
Markdown 语法手册 (完整整理版)
Markdown快速入门
现在博文写作次数渐渐变多,经常看到很多园友的博文样式都非常的美观,个人虽然是个土鳖,但对美也是有很强需求的,同时由于最近将要上线一个博客项目,因此也很关心如何可以更高效的编辑和发布博文。之前一直使用word,在发布时始终存在一个格式转换的问题,很多word特有样式都会失效,需要手动微调,而且也会变得没那么美观,比如SmartArt需要重新切图上传,代码需要重新复制插入,表格的尺寸等也有很大的失真等,困扰了我很久。最近看到很多博主推荐markdown编辑器,并且博客园也支持,git的readme的文件均是.m
用户1216676
2018/01/24
1.2K0
Markdown快速入门
Markdown语法hexo常用汇总
Markdown 是一种轻量级标记语言,它允许人们使用易读易写的纯文本格式编写文档。
CtrlX
2022/08/10
3.4K0
Markdown语法hexo常用汇总
Markdown 语法教程
Markdown 语言在 2004 由约翰·格鲁伯(英语:John Gruber)创建。
用户1040278
2022/10/21
1.6K0
Markdown语法
Markdown 段落没有特殊的格式,直接编写文字就好,段落的换行是使用两个以上空格加上回车。或者
SakuraTears
2022/01/13
1.7K0
Markdown语法
markdown语法简介
Markdown 是什么 Markdown 是一种轻量级标记语言。 它允许人们“使用易读易写的纯文本格式编写文档,然后转换成有效的XHTML(或者HTML)文档”。 Markdown 吸
子勰
2018/05/22
6370
Markdown笔记 | 一篇最详细的Markdown 教程 --> 收好
Markdown是一种可以使用普通文本编辑器编写的标记语言,通过简单的标记语法,它可以使普通文本内容具有一定的格式。Markdown具有一系列衍生版本,用于扩展Markdown的功能(如表格、脚注、内嵌HTML等等),这些功能原初的Markdown尚不具备,它们能让Markdown转换成更多的格式,例如LaTeX,Docbook。Markdown增强版中比较有名的有Markdown Extra、MultiMarkdown、 Maruku等。这些衍生版本要么基于工具,如Pandoc;要么基于网站,如GitHub和Wikipedia,在语法上基本兼容,但在一些语法和渲染效果上有改动。
野原测试开发
2019/07/10
31K0
相关推荐
markdown语法
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验