首页 > 其他分享 >Day14-设计模式之迭代器模式

Day14-设计模式之迭代器模式

时间:2023-07-05 21:35:51浏览次数:67  
标签:遍历 Student 迭代 Day14 student new 设计模式 public

设计模式之迭代器模式

一、概念

定义:提供一种遍历集合元素的统一接口,用一致的方法遍历集合元素,不需要知道集合对象的底层表示,即:不暴露其内部的结构

  • 意图:如果我们的集合元素是用不同方式实现的,有数组、集合或者其他方式。当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,可以考虑使用迭代器模式解决。

二、角色职责

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

三、类图

image-20230613214652633

四、案例实现

【例】定义一个可以存储学生对象的容器对象,将遍历该容器的功能交由迭代器实现

类图如下:

  1. 创建一个学生类
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    /**
     * 姓名
     */
    private String name;

    /**
     * 年龄
     */
    private Integer age;
}
  1. 定义迭代器接口,声明hasNext、next方法:
public interface StudentIterator {

    /**
     * 是否还有元素
     *
     * @return
     */
    boolean hasNext();

    /**
     * 当前元素
     *
     * @return
     */
    Student next();

    /**
     * 移除当前元素
     */
    void remove(Student student);
}
  1. 定义具体的迭代器类,重写所有的抽象方法:
public class StudentIteratorImpl implements StudentIterator {


    /**
     * 要迭代的集合
     */
    private List<Student> list;

    /**
     * 当前元素索引
     */
    private int position = 0;

    public StudentIteratorImpl(List<Student> list) {
        this.list = list;
    }

    @Override
    public boolean hasNext() {
        return position < list.size();
    }

    @Override
    public Student next() {
        Student currentStudent = list.get(position);
        position++;
        return currentStudent;
    }

    @Override
    public void remove(Student student) {
        list.remove(student);
    }
}
  1. 定义抽象容器类,包含添加元素,删除元素,获取迭代器对象的方法:
public interface StudentAggregate {

    /**
     * 添加元素
     *
     * @param student
     */
    void addStudent(Student student);


    /**
     * 获取迭代器
     *
     * @return
     */
    StudentIterator getStudentIterator();
}
  1. 定义具体的容器类,重写所有的方法:
public class StudentAggregateImpl implements StudentAggregate{

    private List<Student> list = new ArrayList<>();

    @Override
    public void addStudent(Student student) {
        list.add(student);
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl(list);
    }
}
  1. 测试类
public class Client {

    public static void main(String[] args) {
        StudentAggregateImpl studentAggregate = new StudentAggregateImpl();
        studentAggregate.addStudent(new Student("张三", 20));
        studentAggregate.addStudent(new Student("李四", 30));
        studentAggregate.addStudent(new Student("王五", 40));
        studentAggregate.addStudent(new Student("赵六", 50));

        StudentIterator studentIterator = studentAggregate.getStudentIterator();

        while (studentIterator.hasNext()) {
            Student student = studentIterator.next();
            if (student.getAge() >= 50) {
                studentIterator.remove(student);
            } else {
                System.out.println(student);
            }
        }
        
    }
}

新增数组元素

public class StudentAggregateImpl002 implements StudentAggregate{

    private Student[] students = new Student[5];
    //保存当前数组的对象个数
    int numOfStudents = 0;

    @Override
    public void addStudent(Student student) {
        students[numOfStudents] = student;
        numOfStudents++;
    }

    @Override
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl002(students);
    }
}
public class StudentIteratorImpl002 implements StudentIterator {


    /**
     * 要迭代的数组
     */
    private Student[] students;

    /**
     * 当前元素索引
     */
    private int position = 0;

    public StudentIteratorImpl002(Student[] students) {
        this.students = students;
    }

    @Override
    public boolean hasNext() {
        if(position >= students.length || students[position] == null) {
            return false;
        }else {
            return true;
        }
    }

    @Override
    public Student next() {
        Student currentStudent = students[position];
        position++;
        return currentStudent;
    }

    @Override
    public void remove(Student student) {
        Student[] removeEle = ArrayUtil.removeEle(students, student);
        students = removeEle;
    }
}
StudentAggregateImpl002 studentAggregate = new StudentAggregateImpl002();
        studentAggregate.addStudent(new Student("张三", 20));
        studentAggregate.addStudent(new Student("李四", 30));
        studentAggregate.addStudent(new Student("王五", 40));
        studentAggregate.addStudent(new Student("赵六", 50));

        StudentIterator studentIterator = studentAggregate.getStudentIterator();
        while (studentIterator.hasNext()) {
            Student student = studentIterator.next();
            if (student.getAge() >= 50) {
                studentIterator.remove(student);
            } else {
                System.out.println(student);
            }
        }

五、总结

  • 1,优点:

    • 它支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。在迭代器模式中只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,我们也可以自己定义迭代器的子类以支持新的遍历方式。
  • 迭代器简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。

    • 在迭代器模式中,由于引入了抽象层,增加新的聚合类和迭代器类都很方便,无须修改原有代码,满足 “开闭原则” 的要求。

    2,缺点:

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

  • 使用场景:

    • 当需要为聚合对象提供多种遍历方式时。
  • 当需要为遍历不同的聚合结构提供一个统一的接口时。

    • 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。

标签:遍历,Student,迭代,Day14,student,new,设计模式,public
From: https://www.cnblogs.com/coolsheep/p/17529832.html

相关文章

  • Day13-设计模式之访问者模式
    设计模式之访问者模式一、概念定义:封装一些作用于某种数据结构中的各元素的操作,它可以在不改变这个数据结构的前提下定义作用于这些元素的新的操作。模式动机:对于存储在一个集合中的对象,他们可能具有不同的类型(即使有一个公共的接口),对于该集合中的对象,可以接受一类称为访问......
  • Day10-设计模式之外观模式
    设计模式之外观模式一、引例当我们现在想要在家通过投影仪看电影,其过程包括关灯,关闭窗帘,打开投影仪,这些家居都是独立的,就会有灯光开关、窗帘开关、投影仪开关。我们需要一步一步的去打开这些开关。如果用代码来实现,就可将灯光,窗帘等都看成一个对象,然后用Client端依次去调用这些......
  • Day11-设计模式之享元模式
    设计模式之享元模式一、意图在面向对象系统的设计和实现中,创建对象是最为常见的操作。这里面就有一个问题:如果一个应用程序使用了太多的对象,就会造成很大的存储开销。特别是对于大量轻量级(细粒度)的对象,比如在文档编辑器的设计过程中,我们如果为每个字母创建一个对象的话,系统可......
  • Day13-设计模式之命令模式
    设计模式之命令模式一、引例我们买了一套智能家电,有照明灯、风扇、冰箱、洗衣机,我们只要在手机上安装app就可以控制对这些家电工作。这些智能家电来自不同的厂家,我们不想对每一种家电都安装一个App,分别控制,我们希望只要一个app就可以控制全部智能家电。要实现一个app控制所......
  • Day12-设计模式之备忘录模式
    设计模式之备忘录模式一、引例案例引入游戏角色状态恢复问题游戏角色有攻击力和防御力,在大战Boss前保存自身的状态(攻击力和防御力),当大战Boss后攻击力和防御力下降,从备忘录对象恢复到大战前的状态。传统的设计方案传统的方式的问题分析一个对象,就对应一个保存对象状态......
  • JAVA设计模式之建造者模式
    设计模式设计模式(DesignPattern)是前辈们对代码开发经验的总结,是解决特定问题的一系列套路。它不是语法规定,而是一套用来提高代码可复用性、可维护性、可读性、稳健性以及安全性的解决方案。总体来说设计模式分为三大类:创建型模式,共五种:工厂方法模式、抽象工厂模式、单例模式、......
  • 有状态的迭代器
    实践为先,先写个错误代码functioniter_pro(arr,b)localindex=0returnfunction()index=index+1ifarr[index]thenreturnarr[index]endendenda={1,2,3,5,4}forviniter_pro,a,0do......
  • 学迭代器遇到的一个问题
    事情是这样的functioniter(arr,index)index=index+1ifarr[index]thenreturnarr[index],indexendenda={1,2,3,5,4}fork,viniter,{1,2,5,6,5,4},0doprint(k)end运行结果:寄将手打的table改成a得......
  • DDD领域设计模式
    微服务设计为什么要选择DDD?其实最近几年微服务架构的思想越来越普及,很多企业已经或者尝试从单体架构向微服务架构转型。微服务也成为很多中大型企业实施中台战略的不二之选。但是在微服务实施过程中有很多问题,单体应用到底应该如何去拆分微服务?边界到底怎么划分?微服务这个微字到......
  • 迭代失败的4个迹象,团队中了几个?快来看看如何解决!
    迭代在Scrum中有着举足轻重的作用,它能将产品愿望清单转化为可操作的任务,将头脑风暴塑造成具体结果。迭代不仅加速了项目交付,甚至还创造了一种责任文化,尤其针对在地理位置上分散的团队。虽然迭代一直是快速推进项目管理的可靠方法,但如果做得不好,它们可能会造成严重的流程不平衡。......