阿里华为等大厂如何实践迭代器模式的?(上)

简介: 定义:行为型,Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。)基本不会有人业务开发使用的模式,没人会单独写一个迭代器,除非是产品性质的开发。迭代器是为容器服务的,例如Collection、Map等,迭代器模式就是为解决遍历这些容器中的元素而生。

1 概念

定义

行为型,Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。)

基本不会有人业务开发使用的模式,没人会单独写一个迭代器,除非是产品性质的开发。

迭代器是为容器服务的,例如Collection、Map等,迭代器模式就是为解决遍历这些容器中的元素而生。

image.png

容器只要负责新增、移除元素即可,遍历由迭代器进行。

角色

Iterator抽象迭代器

抽象迭代器负责定义访问和遍历元素的接口,而且基本上是有固定的3个方法:

  first()获得第一个元素

  next()访问下一个元素

  hasNext()是否已经访问到底部


ConcreteIterator具体迭代器

具体迭代器角色要实现迭代器接口,完成容器元素的遍历。


Aggregate抽象容器

容器角色负责提供创建具体迭代器角色的接口,必然提供一个类似createIterator()这样的方法,在Java中一般是iterator()方法。


Concrete Aggregate具体容器

具体容器实现容器接口定义的方法,创建出容纳迭代器的对象。


我们来看迭代器模式的通用源代码


抽象迭代器

public interface Iterator<E> {
    boolean hasNext();
    E next();
    default void remove() {
        throw new UnsupportedOperationException("remove");
    }
    default void forEachRemaining(Consumer<? super E> action) {
        Objects.requireNonNull(action);
        while (hasNext())
            action.accept(next());
    }
}

具体迭代器

public class ConcreteIterator implements Iterator {
     private Vector vector = new Vector();
     //定义当前游标
     public int cursor = 0;
     @SuppressWarnings("unchecked")
     public ConcreteIterator(Vector _vector){
             this.vector = _vector;
     }
     //判断是否到达尾部
     public boolean hasNext() {
             if(this.cursor == this.vector.size()){
                    return false;
             }else{
                    return true;
             }
     }
     //返回下一个元素
     public Object next() {
             Object result = null;
             if(this.hasNext()){
                    result = this.vector.get(this.cursor++);
             }else{
                    result = null;
             }
             return result;
     }
     //删除当前元素
     public boolean remove() {
             this.vector.remove(this.cursor);
             return true;
     }
}

开发系统时,迭代器的删除方法应该完成两个逻辑:

  • 删除当前元素
  • 当前游标指向下一个元素
  • 抽象容器
public interface Aggregate {
     //是容器必然有元素的增加
     public void add(Object object);
     //减少元素
     public void remove(Object object);
     //由迭代器来遍历所有的元素
     public Iterator iterator();
}
  • 具体容器

         
  • 场景类
public class Client {
     public static void main(String[] args) {
             //声明出容器
             Aggregate agg = new ConcreteAggregate();
             //产生对象数据放进去
             agg.add("abc");
             agg.add("aaa");
             agg.add("1234");     
             //遍历一下
             Iterator iterator = agg.iterator();
             while(iterator.hasNext()){
                     System.out.println(iterator.next());
             }
     }
}

2 适用场景

  • 访问一个集合对象的内容而无需暴露它的内部表示
  • 为遍历不同的集合结构提供一个统一的接口

我们在例子中使用了迭代器模式后为什么使原本简单的应用变得复杂起来了呢?那是因为我们在简单的应用中使用了迭代器,在哪?

注意这段话

for(IProject project:projectList)

它为什么能够运行起来?还不是因为ArrayList已经实现了iterator()方法,我们才能如此简单地应用。


从JDK 1.2版本开始增加java.util.Iterator这个接口,并逐步把Iterator应用到各个聚集类(Collection)中,我们来看JDK 1.5的API帮助文件,你会看到有一个叫java.util.Iterable的接口

看看有多少个接口继承了它:

BeanContext,BeanContextServices,BlockingQueue,Collection,List,Queue,Set,SortedSet

再看看有它多少个实现类:AbstractCollection,AbstractList,AbstractQueue,AbstractSequentialList,AbstractSet,ArrayBlockingQueue,ArrayList,AttributeList,BeanContextServicesSupport,BeanContextSupport,ConcurrentLinkedQueue,CopyOnWriteArrayList,CopyOnWriteArraySet,DelayQueue,EnumSet,HashSet,JobStateReasons,LinkedBlockingQueue,LinkedHashSet,LinkedList,PriorityBlockingQueue,PriorityQueue,RoleList,RoleUnresolvedList,Stack,SynchronousQueue,TreeSet,Vector

基本上我们经常使用的类都在这个表中了,也正是因为Java把迭代器模式已经融入到基本API中了,我们才能如此轻松、便捷。


我们再来看看Iterable接口。java.util.Iterable接口只有一个方法:iterator(),也就说,通过iterator()这个方法去遍历聚集类中的所有方法或属性,基本上现在所有的高级语言都有Iterator这个接口或者实现,Java已经把迭代器给我们准备好了,我们再去写迭代器,就有点多余了。所以呀,这个迭代器模式也有点没落了,基本上很少有项目再独立写迭代器了,直接使用Collection下的实现类就可以完美地解决问题。


迭代器现在应用得越来越广泛了,甚至已经成为一个最基础的工具。一些大师级人物甚至建议把迭代器模式从23个模式中删除,为什么呢?就是因为现在它太普通了,已经融入到各个语言和工具中了,比如PHP中你能找到它的身影,Perl也有它的存在,甚至是前台的页面技术AJAX也可以有它的出现(如在Struts2中就可以直接使用iterator)。基本上,只要你不是在使用那些古董级(指版本号)的编程语言的话,都不用自己动手写迭代器。

3 优点

分离了集合对象的遍历行为

4 缺点

类的个数成对增加

目录
相关文章
|
前端开发 架构师 搜索推荐
COLA 4.0:直击应用架构本质的最佳实践
COLA 4.0:直击应用架构本质的最佳实践
2033 0
COLA 4.0:直击应用架构本质的最佳实践
|
6月前
|
运维 负载均衡 Cloud Native
带你读《浅谈阿里云通用产品线Serverless的小小演化史》------导论
浅谈阿里云通用产品线Serverless的小小演化史(1)
|
运维 数据可视化 中间件
一文搞懂SaaS、PaaS、IaaS的概念和异同
一文搞懂SaaS、PaaS、IaaS的概念和异同
|
架构师 数据挖掘 程序员
C++ 类设计和实现的十大最佳实践
C++ 类设计和实现的十大最佳实践
565 0
C++ 类设计和实现的十大最佳实践
|
缓存 SpringCloudAlibaba 算法
阿里新一代微服务,内部大佬手抄的笔记+脑图不容错过,全是精华
今天来聊聊Spring Cloud Alibaba,它是Spring Cloud规范的一套实现,为分布式应用程序开发提供一站式解决方案。它包含开发分布式应用程序所需的所有组件,使您可以轻松地使用Spring Cloud开发应用程序。Spring Cloud Alibaba中的组件,基本都是由阿里内部中间件转化而来,经历过多次双十一的考验,这也就意味着,Spring Cloud Alibaba有着充足的场景,验证了它对于高并发的抗压能力。
阿里新一代微服务,内部大佬手抄的笔记+脑图不容错过,全是精华
|
存储 SQL 监控
郭炜:讨论 ClickHouse 的未来,至少要了解它的设计理念
几乎每一个月就更新一次的 ClickHouse,在过去的 2021 年实现了哪些优秀的功能呢?现在的 ClickHouse 适合在哪些场景下使用呢?未来 ClickHouse 发展的重点又在哪里呢?从 2019 年突然火爆起来的 ClickHouse 作为一匹黑马,在云原生场景下,是一匹千里马,还是明日黄花呢?
595 0
郭炜:讨论 ClickHouse 的未来,至少要了解它的设计理念
|
Java API Spring
写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理(上)
Hello,各位小伙伴们,宣布一个好消息: 咱们的公号终于有留言功能了!!! 以后小伙们就可以在留言区留言跟阿粉一起交流咯~
写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理(上)
|
前端开发 Dubbo Java
写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理(下)
Hello,各位小伙伴们,宣布一个好消息: 咱们的公号终于有留言功能了!!! 以后小伙们就可以在留言区留言跟阿粉一起交流咯~
写了一套优雅接口之后,领导让我给大家讲讲这背后的技术原理(下)
|
Java 数据库连接 容器
阿里华为等大厂如何实践迭代器模式的?(下)
定义:行为型,Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。) 基本不会有人业务开发使用的模式,没人会单独写一个迭代器,除非是产品性质的开发。 迭代器是为容器服务的,例如Collection、Map等,迭代器模式就是为解决遍历这些容器中的元素而生。
107 0
阿里华为等大厂如何实践迭代器模式的?(下)
|
Java BI API
阿里华为等大厂如何实践迭代器模式的?(中)
定义:行为型,Provide a way to access the elements of an aggregate object sequentially without exposing its underlying representation.(它提供一种方法访问一个容器对象中各个元素,而又不需暴露该对象的内部细节。) 基本不会有人业务开发使用的模式,没人会单独写一个迭代器,除非是产品性质的开发。 迭代器是为容器服务的,例如Collection、Map等,迭代器模式就是为解决遍历这些容器中的元素而生。
84 0
阿里华为等大厂如何实践迭代器模式的?(中)