0
点赞
收藏
分享

微信扫一扫

linux系统上做性能压力测试 —— 筑梦之路

文章目录

⬇️本系列 - 结构型模式 - 链接🔗

⬇️本系列 - 行为型模式 - 链接🔗

在这里插入图片描述

1 迭代器模式(Iterator Pattern)★★★

  迭代器模式(Iterator Pattern)是 Java 和 .Net 编程环境中非常常用的设计模式。这种模式用于顺序访问集合对象的元素,不需要知道集合对象的底层表示。迭代器模式属于行为型模式。

1.1 介绍

  • 意图:提供一种方法顺序访问一个聚合对象中各个元素, 而又无须暴露该对象的内部表示。

  • 主要解决:遍历一个聚合对象。

  • 何时使用:多个类相互耦合,形成了网状结构。

  • 如何解决:把在元素之间游走的责任交给迭代器,而不是聚合对象。

  • 关键代码:定义接口:hasNext, next。

  • 应用实例
      1️⃣ JAVA 中的 iterator

  • 优点
      1️⃣ 它支持以不同的方式遍历一个聚合对象。
      2️⃣ 迭代器简化了聚合类。
      3️⃣ 在同一个聚合上可以有多个遍历。
      4️⃣ 在迭代器模式中,增加新的聚合类和迭代器类都很方便,无须修改原有代码。

  • 缺点
      1️⃣ 由于迭代器模式将存储数据和遍历数据的职责分离,增加新的聚合类需要对应增加新的迭代器类,类的个数成对增加,这在一定程度上增加了系统的复杂性。

  • 使用场景
      1️⃣ 访问一个聚合对象的内容而无须暴露它的内部表示。
      2️⃣ 需要为聚合对象提供多种遍历方式。
      3️⃣ 为遍历不同的聚合结构提供一个统一的接口。

  • 注意事项
      1️⃣ 迭代器模式就是分离了集合对象的遍历行为,抽象出一个迭代器类来负责,这样既可以做到不暴露集合的内部结构,又可让外部代码透明地访问集合内部的数据。

1.2 概述

  迭代器模式是一种强大的设计模式,它通过将遍历逻辑封装在迭代器对象中,实现了对集合对象的统一访问和操作,从而简化了客户端代码并提高了代码的可读性和可维护性。

  在Java中,迭代器模式得到了广泛的应用。Java集合框架(Collections Framework)中的Iterator接口就是迭代器模式的一个典型实现。通过实现Iterator接口,Java集合类(如ArrayList、LinkedList等)提供了统一的遍历方式,使得客户端可以方便地访问和操作集合中的元素。

1.3 迭代器模式的结构

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

1.4 中介者模式的优缺点

优点

  • 它支持以不同的方式遍历一个聚合对象,在同一个聚合对象上可以定义多种遍历方式。在迭代器模式中只需要用一个不同的迭代器来替换原有迭代器即可改变遍历算法,我们也可以自己定义迭代器的子类以支持新的遍历方式。

  • 迭代器简化了聚合类。由于引入了迭代器,在原有的聚合对象中不需要再自行提供数据遍历等方法,这样可以简化聚合类的设计。

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

缺点

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

1.5 中介者模式的使用场景

  • 当需要为聚合对象提供多种遍历方式时。
  • 当需要为遍历不同的聚合结构提供一个统一的接口时。
  • 当访问一个聚合对象的内容而无须暴露其内部细节的表示时。



2 案例一

2.1 需求

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

  类图如下:

在这里插入图片描述

2.2 代码实现

  定义迭代器接口,声明hasNext、next方法

抽象迭代器角色接口(接口)
/**
 * 抽象迭代器角色接口
 *
 * @author LiaoYuXing-Ray
 **/
public interface StudentIterator {

    // 判断是否还有元素
    boolean hasNext();

    // 获取下一个元素
    Student next();
}

  定义具体的迭代器类,重写所有的抽象方法

具体迭代器角色类(类)
import java.util.List;

/**
 * 具体迭代器角色类
 *
 * @author LiaoYuXing-Ray
 **/
public class StudentIteratorImpl implements StudentIterator {

    private final List<Student> list;
    private int position = 0; // 用来记录遍历时的位置

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

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

    public Student next() {
        // 从集合中获取指定位置的元素
        Student currentStudent = list.get(position);
        position++;
        return currentStudent;
    }
}

  定义抽象容器类,包含添加元素,删除元素,获取迭代器对象的方法

抽象聚合角色接口(接口)
/**
 * 抽象聚合角色接口
 *
 * @author LiaoYuXing-Ray
 **/
public interface StudentAggregate {

    // 添加学生功能
    void addStudent(Student stu);

    // 删除学生功能
    void removeStudent(Student stu);

    // 获取迭代器对象功能
    StudentIterator getStudentIterator();
}

  定义具体的容器类,重写所有的方法

具体的容器类(类)

import java.util.ArrayList;
import java.util.List;


/**
 * 具体的容器类
 *
 * @author LiaoYuXing-Ray
 **/
public class StudentAggregateImpl implements StudentAggregate {

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

    public void addStudent(Student stu) {
        list.add(stu);
    }

    public void removeStudent(Student stu) {
        list.remove(stu);
    }

    // 获取迭代器对象
    public StudentIterator getStudentIterator() {
        return new StudentIteratorImpl(list);
    }
}

  迭代器元素类

学生类(类)
/**
 * 学生类
 *
 * @author LiaoYuXing-Ray
 **/
public class Student {
    private String name;
    private String number;

    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", number='" + number + '\'' +
                '}';
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getNumber() {
        return number;
    }

    public void setNumber(String number) {
        this.number = number;
    }

    public Student(String name, String number) {
        this.name = name;
        this.number = number;
    }

    public Student() {
    }
}

测试类
/**
 * 测试类
 *
 * @author LiaoYuXing-Ray
 **/
public class Client {
    public static void main(String[] args) {
        // 创建聚合对象
        StudentAggregateImpl aggregate = new StudentAggregateImpl();
        // 添加元素
        aggregate.addStudent(new Student("张三","001"));
        aggregate.addStudent(new Student("李四","002"));
        aggregate.addStudent(new Student("王五","003"));
        aggregate.addStudent(new Student("赵六","004"));

        // 遍历聚合对象

        // 1.获取迭代器对象
        StudentIterator iterator = aggregate.getStudentIterator();
        // 2.遍历
        while(iterator.hasNext()) {
            // 3.获取元素
            Student student = iterator.next();
            System.out.println(student.toString());
        }
    }
}

  代码运行结果如下:

	Student{name='张三', number='001'}
	Student{name='李四', number='002'}
	Student{name='王五', number='003'}
	Student{name='赵六', number='004'}

3 案例二

3.1 需求

  我们将创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。

  IteratorPatternDemo,我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。

在这里插入图片描述

3.2 代码实现

步骤 1

  创建接口

Iterator.java
public interface Iterator {
   public boolean hasNext();
   public Object next();
}
Container.java
public interface Container {
   public Iterator getIterator();
}

步骤 2

  创建实现了 Container 接口的实体类。该类有实现了 Iterator 接口的内部类 NameIterator。

NameRepository.java
public class NameRepository implements Container {
   public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};
 
   @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;
      }     
   }
}

步骤 3

  使用 NameRepository 来获取迭代器,并打印名字。

IteratorPatternDemo.java
public class IteratorPatternDemo {
   
   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);
      }  
   }
}

步骤 4

  执行程序,输出结果:

	Name : Robert
	Name : John
	Name : Julie
	Name : Lora



4 JDK源码解析

  迭代器模式在JAVA的很多集合类中被广泛应用,接下来看看JAVA源码中是如何使用迭代器模式的。

List<String> list = new ArrayList<>();
Iterator<String> iterator = list.iterator(); //list.iterator()方法返回的肯定是Iterator接口的子实现类对象
while (iterator.hasNext()) {
    System.out.println(iterator.next());
}

  看完这段代码是不是很熟悉,与我们案例一的代码实现基本类似。单列集合都使用到了迭代器,我们以ArrayList举例来说明

  • List:抽象聚合类
  • ArrayList:具体的聚合类
  • Iterator:抽象迭代器
  • list.iterator():返回的是实现了 Iterator 接口的具体迭代器对象

  具体看看ArrayList的代码实现

public class ArrayList<E> extends AbstractList<E>
        implements List<E>, RandomAccess, Cloneable, java.io.Serializable {
    
    public Iterator<E> iterator() {
        return new Itr();
    }
    
    private class Itr implements Iterator<E> {
        int cursor;       // 下一个要返回元素的索引
        int lastRet = -1; // 上一个返回元素的索引
        int expectedModCount = modCount;

        Itr() {}
		
        //判断是否还有元素
        public boolean hasNext() {
            return cursor != size;
        }

        //获取下一个元素
        public E next() {
            checkForComodification();
            int i = cursor;
            if (i >= size)
                throw new NoSuchElementException();
            Object[] elementData = ArrayList.this.elementData;
            if (i >= elementData.length)
                throw new ConcurrentModificationException();
            cursor = i + 1;
            return (E) elementData[lastRet = i];
        }
        ...
}

  这部分代码大致就是在 iterator 方法中返回了一个实例化的 Iterator 对象。Itr是一个内部类,它实现了 Iterator 接口并重写了其中的抽象方法。




本文是博主的粗浅理解,可能存在一些错误或不完善之处,如有遗漏或错误欢迎各位补充,谢谢

  如果觉得这篇文章对您有所帮助的话,请动动小手点波关注💗,你的点赞👍收藏⭐️转发🔗评论📝都是对博主最好的支持~


举报

相关推荐

0 条评论