迭代器模式定义

迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示。

Java 开发过程中遍历是常用的。如下边程序:

for(int i =0 ;i<arr.length;i++){
System.out.println(arr[i]);
}

for语句中i++每次循环自增1,迭代到下一元素。将循环变量的作用抽象化,通用化后形成的模式,在设计模式中成为Iterator模式。

实现场景

将书(Book)放到书架(BookShelf)中,并将书名按顺序显示。



程序示例

Aggregate 接口:

所要遍历的集合的接口。实现了该接口的类将成为一个可以保存多个元素的集合,类似数组。

public interface Aggregate{
public abstract Iterator iterator();
}

Aggregate接口中声明的方法为iterator,作用为生成一个用于遍历的迭代器。

Iterator 接口:

作用为遍历集合中元素,相当于循环语句中的循环变量(for(int i =0 ;i<arr.lenth;i++),具体实现一个顺序遍历的迭代器。

public interface Iterator{
public abstract boolean hasNext();
public abstract Object next();
}

hasNext() 方法判断是否存在下一个,next()方法获取下一个元素。

特殊说明下,next方法在获取元素的同时,要将计数器向下一个元素的计数加一。获取的是当前元素,并指向下一个元素。

Book类:

普通类,书名field 获取书名的getName()方法。构造函数初始化书名。

public class Book{
private String name ;
public Book(String name){
this.name=name;
}
public String getName(){
return name;
}
}

BookShelf 类:

书架类,作为存放书的集合类,实现Aggregate接口。实现了Aggregate接口的iterator方法。

public class BookShelf implements Aggregate {

    private List<Book> books;

    public BookShelf() {
this.books = new ArrayList<Book>();
} public Book getBookAt(int index) {
return books.get(index);
} public void appendBook(Book book) {
books.add(book);
} public int getLength() {
return books.size();
} public Iterator iterator() {
return new BookShelfIterator(this);
}
}

主要点在iterator方法,方法返回了遍历书架时要用的BookShelfIterator类作为书架的迭代器。当外部要遍历书架时会调用该方法。

BookShelfIterator类:

public class BookShelfIterator implements Iterator {

    private BookShelf bookShelf;
private int index; public BookShelfIterator(BookShelf bookShelf) {
this.bookShelf = bookShelf;
this.index = 0;
} public boolean hasNext() {
if (index < bookShelf.getLength()) {
return true;
} else {
return false;
}
} public Object next() {
Book book = bookShelf.getBookAt(index);
index++;
return book;
}
}

作为一个迭代器,要实现Iterator接口。index为迭代器当前所指向的下标。

hasNext判断还有没有下一本。通过下标和总数比较判断。

next获取当前书,并指向下一个。

Main类:

public class Main {
public static void main(String[] args) {
BookShelf bookShelf = new BookShelf();
bookShelf.appendBook(new Book("Around the World in 80 Days"));
bookShelf.appendBook(new Book("Bible"));
bookShelf.appendBook(new Book("Cinderella"));
bookShelf.appendBook(new Book("Daddy-Long-Legs"));
Iterator it = bookShelf.iterator();
while (it.hasNext()) {
Book book = (Book) it.next();
System.out.println(book.getName());
}
}
} 控制台:
----------------------------------
Around the World in 80 Days
Bible
Cinderella
Daddy-Long-Legs
----------------------------------

Iterator模式中各角色的作用

  • Iterator(迭代器):该角色责任定义按顺序逐个遍历元素的接口。程序中,由Iterator接口扮演,定义了hasNext和next两个方法。
  • Concretelterator(具体的迭代器):该角色负责实现Iterator角色所定义的接口.该角色包含了遍历集合所必须的信息。
  • Aggregate(集合):该角色负责定义创建Iterator角色的接口。这个接口是一个方法会创建出一个,按照顺序访问保存在我内部元素的人。
  • ConcreteAggregate(具体集合):该角色负责实现Aggregate角色所定义的接口。他会创建出具体的Iterator角色,也就是ConcreteIterator,也就是实例中的BookShelf。

Iterator 模式的类图:

学习设计模式的重点

不管实现如何变化都可以使用Iterator

为什么一定要考虑引入Iterator这种复杂的设计模式呢?

如果是数组,直接使用for玄幻语句进行遍历处理不就可以了吗?

为什么要在集合之外引入Iterator角色?

一个重要的理由:引入Iterator后可以将遍历与实现分离开来。

while (it.hasNext()) {

Book book = (Book) it.next();

System.out.println(book.getName());

}

这里使用了Iterator的hasNext方法和next方法,并没有调用BookShelf的方法。也就是说,这里的while循环并不依赖于BookShelf的实现。

例如在BookShelf的开发人员决定放弃用数组来管理书本,而是用Java.util.Vector取而代之,会怎么样呢。不管BookShelf如何变化,只要BookShelf的iterator方法能正确的返回Iterator的实力,即使不对上面的while循环做任何修改,代码都可以正常工作。

对于BookShelf的调用者来说真的太方便了。

设计模式的作用就是帮助我们编写可复用的类。

所谓可复用,就是指将类实现为组件,当一个组件发生改变时,不需要对其他组件进行修改或是只需要很小的修改即可应对。

这也就能理解为什么在示例程序中iterator方法返回值不是bookshelfiter类而是iter类型了。这表明,程序就是要使用iterator的方法进行编程而不是bookshelfiterator的方法。

难以理解抽象类和接口

难以理解抽象类和接口的人常常食用ConcreteAggregate角色和ConcreteIterator角色编程,而不是用Aggregate接口和Iterator接口,他们总想用具体的类解决所有的问题。

但是如果只使用具体的类来解决问题,很容易导致类之间的强耦合,这些类也难以作为组件被再次利用,为了弱化类之间的耦合,进而使得类更加容易作为组件被再次利用,我们需要引入抽象类和接口。

这种思想要贯穿整个设计模式。

Aggregate和Iterator的对应

多个Iterator

将遍历功能至于Aggregate角色之外是Iterator模式的一个特征。这个特征可以针对一个ConcreteAggregate角色编写多个ConcreteIterator角色。

预先介绍几种设计模式:

Vistor模式

iterator模式是从集合中一个一个取出元素进行遍历,但是并没有在Iterator接口中生病对取出的元素进行任何处理。

Vistor模式则在遍历元素集合的过程中,对元素进行相同的处理。

在遍历集合的过程中对元素进行固定的处理是常有的需求。Visitor模式正是为了应对这种需求而出现的。在方文元素集合的过程中对元素进行相同的处理,这种模式就是Vistor模式。

Composite模式

Composite模式是具有递归结构的模式,在其中使用Iterator模式比较困难。

Factory Method 模式

在iterator方法中生成Iterator的实力时可能会使用Factory Method模式。

作者:嘟嘟碰碰叮叮当当

链接:https://www.jianshu.com/p/3dd7b4e73561

来源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

简单的了解下Java设计模式:迭代器模式(转载)的更多相关文章

  1. java设计模式——迭代器模式

    一. 定义与类型 定义:提供一种方法,顺序访问一个集合对象中的各个元素,而又不暴露该对象的内部表示 类型:行为型. 二. 使用场景 (1) 访问一个集合对象的内容而无需暴露它的内部表示 (2)  为遍 ...

  2. Java设计模式の迭代器模式

    迭代器模式定义 迭代器模式(Iterator),提供一种方法顺序访问一个聚合对象中的各种元素,而又不暴露该对象的内部表示. 迭代器模式的角色构成 (1)迭代器角色(Iterator):定义遍历元素所需 ...

  3. JAVA 设计模式 迭代器模式

    用途 迭代器模式 (Iterator) 提供一种方法顺序访问一个聚合对象中各个元素,而又不暴露该对象的内部表示. 迭代器模式是一种行为型模式. 结构

  4. JAVA设计模式---迭代器模式

    1.定义: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 2.实例:1)需求: 菜单(煎饼屋菜单.餐厅菜单和咖啡菜单)采用不同的集合存取(ArrayList,String[] ...

  5. java设计模式----迭代器模式和组合模式

    迭代器模式: 提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示. 设计原则: 单一责任:一个类应该只有一个引起变化的原因 组合模式: 允许你将对象组合成树形结构来表现“整体/部分” ...

  6. 19. 星际争霸之php设计模式--迭代器模式

    题记==============================================================================本php设计模式专辑来源于博客(jymo ...

  7. Java设计模式——组合模式

    JAVA 设计模式 组合模式 用途 组合模式 (Component) 将对象组合成树形结构以表示“部分-整体”的层次结构.组合模式使得用户对单个对象和组合对象的使用具有唯一性. 组合模式是一种结构型模 ...

  8. Java设计模式——外观模式

    JAVA 设计模式 外观模式 用途 外观模式 (Facade) 为子系统中的一组接口提供一个一致的界面,此模式定义了一个高层接口,这个接口使得这一子系统更加容易使用. 外观模式是一种结构型模式. 结构

  9. 【设计模式】Java设计模式 -工厂模式

    [设计模式]Java设计模式 -工厂模式 不断学习才是王道 继续踏上学习之路,学之分享笔记 总有一天我也能像各位大佬一样 一个有梦有戏的人 @怒放吧德德 分享学习心得,欢迎指正,大家一起学习成长! 目 ...

随机推荐

  1. list.add(int index, E element)和list.addAll(list1)

    List.add(int index, E element): 在列表的指定位置插入指定元素(可选操作).将当前处于该位置的元素(如果有的话)和所有后续元素向右移动(在其索引中加 1). 参数:ind ...

  2. 正月十五吃汤圆CountDownLatch

    CountDownLatch实际应用 今天是正月十五,给大家拜个晚年啦! 元宵节是中国传统节日,吃汤圆不能少啊,今天我们统计下"叫练"吃汤圆时间,并用代码模拟下叫练吃汤圆!其中用到 ...

  3. 第45天学习打卡(Set 不安全 Map不安全 Callable 常用的辅助类 读写锁 阻塞队列 线程池)

    Set不安全  package com.kuang.unsafe; ​ import java.util.*; import java.util.concurrent.CopyOnWriteArray ...

  4. CVE-2019-2618 任意文件上传

    漏洞描述:CVE-2019-2618漏洞主要是利用了WebLogic组件中的DeploymentService接口,该接口支持向服务器上传任意文件.攻击者突破了OAM(Oracle Access Ma ...

  5. FreeBSD 12.2 已经发布 从现有版本更新到12

    #freebsd-update -r 12.2-RELEASE upgrade 如果提示更新第三方软件后,再执行freebsd-update install , 请输入 #pkg update &am ...

  6. P2188 小Z的 k 紧凑数 题解(数位DP)

    题目链接 小Z的 k 紧凑数 解题思路 数位DP,把每一个数位的每一个数对应的可能性表示出来,然后求\(num(1,r)-num(1,l-1)\),其中\(num(i,j)\)表示\([i,j]\)区 ...

  7. 「NOIP模拟赛」Round 3

    Tag 计数+LIS, 二分+ST表, 计数+记搜 A. 改造二叉树 Description 题面 Solution 如果目标序列非严格递增,或者说目标序列是不下降的,那么答案就是 \(n\) 减去最 ...

  8. Shtml、html、xhtml、htm以及SSI的了解与认识(转载)

    Shtml.html.xhtml.htm以及SSI的了解与认识(转载) 一.htm.html.shtml网页区别(博客园) 文章链接:https://www.cnblogs.com/Renyi-Fan ...

  9. beego框架panic: 'GetSecurityInf' method doesn't exist in the controller CorporateInfcontroller问题解决

    在使用beego框架时,出现类似于panic: 'GetSecurityInf' method doesn't exist in the controller CorporateInfcontroll ...

  10. 正则表达式如何直接在EXCEL中使用?

    正则表达式,相信大家都不陌生.但在我们最常用的办公软件EXCEL中,目前没有可直接使用正则表达式的函数(至少10版本的EXCEL没有),那么今天我就分享下如何在EXCEL中自定义正则函数. 一.提需求 ...