大聪明教你学Java设计模式 | 第十四篇:迭代器模式

1,017 阅读4分钟

前言

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第19天,点击查看活动详情

🍊作者简介: 不肯过江东丶,一个来自二线城市的程序员,致力于用“猥琐”办法解决繁琐问题,让复杂的问题变得通俗易懂。

🍊支持作者: 点赞👍、关注💖、留言💌~

大聪明在写代码的过程中发现设计模式的影子是无处不在,设计模式也是软件开发人员在软件开发过程中面临的一般问题的解决方案。大聪明本着“独乐乐不如众乐乐”的宗旨与大家分享一下设计模式的学习心得。

迭代器模式

🍓🍓什么是迭代器模式🍓🍓

在讲解迭代器模式之前,我们先来看一下它的定义👇

迭代器模式(Iterator),提供一种可以顺序访问一个聚合对象中的各种元素的方法,同时又不暴露该对象的内部表示。
🍋P.S. 迭代器模式的定义很简单,只有短短一句话,这也就说明了迭代器模式相对来说更容易理解。

在我们开发的过程中,经常要访问一个聚合对象中的各个元素,比如链表的遍历。我们在遍历链表时,通常是将链表的创建和遍历都放在同一个类中,但这种方式不利于程序的扩展,如果要更换遍历方法就必须修改程序源代码,这显然是违背了 “开闭原则”。看到这可能有小伙伴会问了:既然将遍历方法封装在类中不可取,那么类中不提供遍历方法,就直接将遍历方法由客户端自己实现是否可行呢?答案也是否定的,因为这样做会带来两个弊端:

  • 暴露了聚合类的内部表示,使其数据不安全
  • 给客户端带带来了麻烦。增加了负担

所以为了解决这种情况,我们就需要用到迭代器模式了。它在客户端访问类与聚合类之间插入了一个迭代器,就可以将聚合对象与其遍历行为进行分离,同时也对客户端访问类隐藏了其内部细节,且满足“单一职责原则”和“开闭原则”,就像 Java 中的 Collection、List 等等都是迭代器模式的良好体现。我们可以总结出来迭代器模式所包含的几个角色:

  • 抽象聚合(Aggregate)角色:定义存储、添加、删除聚合对象以及创建迭代器对象的接口。
  • 具体聚合(ConcreteAggregate)角色:实现抽象聚合类,返回一个具体迭代器的实例。
  • 抽象迭代器(Iterator)角色:定义访问和遍历聚合元素的接口,通常包含 hasNext()、first()、next() 等方法。
  • 具体迭代器(Concretelterator)角色:实现抽象迭代器接口中所定义的方法,完成对聚合对象的遍历,记录遍历的当前位置。

🍓🍓迭代器模式的实现🍓🍓

接下来我们就通过代码简单的实现一下迭代器模式👇

🍎创建接口🍎

/**
 * @description: Iterator
 * @author: 庄霸.liziye
 * @create: 2022-04-15 11:03
 **/
public interface Iterator {

    public boolean hasNext();
    
    public Object next();
    
}
/**
 * @description: Container
 * @author: 庄霸.liziye
 * @create: 2022-04-15 11:03
 **/
public interface Container {

    public Iterator getIterator();

}

🍎创建实现 Container 接口的实体类🍎

/**
 * 遍历用户名
 * @description: NameRepository
 * @author: 庄霸.liziye
 * @create: 2022-04-15 11:04
 **/
public class NameRepository implements Container{
    public String[] names = {"张三", "李四", "李四", "王五", "赵六"};

    @Override
    public Iterator getIterator() {
        return new NameIterator();
    }

    private class NameIterator implements Iterator {

        int index;

        @Override
        public boolean hasNext() {
            if(index < names.length){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names[index++];
            }
            return null;
        }
    }
}

🍎使用 NameRepository 来获取迭代器,并打印用户名🍎

/**
 * @description: Test
 * @author: 庄霸.liziye
 * @create: 2022-04-15 11:10
 **/
public class Test {

    public static void main(String[] args) {
        NameRepository namesRepository = new NameRepository();

        for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
            String name = (String)iter.next();
            System.out.println("Name : " + name);
        }
    }
}

🍎代码运行结果🍎

在这里插入图片描述

🍓🍓迭代器模式的优、缺点🍓🍓

最后我们总结一下迭代器模式的优点与缺点👇

🍌🍌优点🍌🍌

🍋 它简化了聚合类,同时支持以不同的方式遍历一个聚合对象;在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

🍌🍌缺点🍌🍌

🍋 增加了类的个数,这在一定程度上增加了系统的复杂性。

小结

本人经验有限,有些地方可能讲的没有特别到位,如果您在阅读的时候想到了什么问题,欢迎在评论区留言,我们后续再一一探讨🙇‍

希望各位小伙伴动动自己可爱的小手,来一波点赞+关注 (✿◡‿◡) 让更多小伙伴看到这篇文章~ 蟹蟹呦(●'◡'●)

如果文章中有错误,欢迎大家留言指正;若您有更好、更独到的理解,欢迎您在留言区留下您的宝贵想法。

爱你所爱 行你所行 听从你心 无问东西