1、iterator 模式
需求:给大家举个例子,现在假设,有一个教室类,里面包含了一堆学生,我现在要遍历教室里的学生,怎么来玩
2、不使用设计模式的代码
/**
* 不用模式实现
*/
public class WithoutIteratorPatternDemo {
/**
* 如果不用任何设计模式,直接去遍历一个类中的集合
* 一旦这个类中对集合的使用改版了,比如从数组 —> map ,还有别的可能
* 你迭代的这块功能,就要改动
* 如果说迭代和业务逻辑和复杂,同时集合类的实现和遍历代码的实现,是两个人开发的
* 成本就很高了,大家有要协调,又要改动
* 简单来说,这种代码,可扩展性,可维护性很差,就是屎一样的代码
* @param args
*/
public static void main(String[] args) {
}
/**
* 从之前的数组换成 hashmap 之后,发现我们的遍历方法又需要改变了
*/
private static void method2() {
Student student1 = new Student("小明");
Student student2 = new Student("小王");
HashMap students = new HashMap<>();
students.put(student1.getName(), student1);
students.put(student2.getName(), student2);
ClassRoom1 classRoom1 = new ClassRoom1();
classRoom1.setStudents(students);
HashMap resultStudents = classRoom1.getStudents();
for (Student student : resultStudents.values()) {
System.out.println(student);
}
}
/**
* 数组的时候遍历集合
*/
private static void method01() {
Student student1 = new Student("小明");
Student student2 = new Student("小王");
Student[] students = new Student[2];
students[0] = student1;
students[1] = student2;
ClassRoom classRoom = new ClassRoom();
classRoom.setStudents(students);
//现在要遍历教室中的学生
Student[] resultStudents = classRoom.getStudents();
for (Student resultStudent : resultStudents) {
System.out.println(resultStudent);
}
}
/**
* 学生类
*/
public static class Student {
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 教室类 1
*/
public static class ClassRoom {
private Student[] students;
public Student[] getStudents() {
return students;
}
public void setStudents(Student[] students) {
this.students = students;
}
}
/**
* 教室类 2
*/
public static class ClassRoom1 {
private HashMap students;
public HashMap getStudents() {
return students;
}
public void setStudents(HashMap students) {
this.students = students;
}
}
}
3、用迭代器模式的时候
/**
* 用迭代器模式的实现
*/
public class IteratorPatternDemo {
public static void main(String[] args) {
// 数组的时候
Student student1 = new Student("小明");
Student student2 = new Student("小王");
Classroom classroom = new Classroom(2);
classroom.addStudent(student1);
classroom.addStudent(student2);
// list的时候
Classroom1 classroom1 = new Classroom1(2);
classroom1.addStudent(student1);
classroom1.addStudent(student2);
java.util.Iterator iterator = classroom1.iterator();
while (iterator.hasNext()){
Object student = iterator.next();
System.out.println(student);
}
}
/**
* 定义一个我们自己的迭代器接口
*/
public interface Iterator{
boolean hasNext();
Object next();
}
/**
* 代表一个集合类
*/
public interface Aggregate{
Iterator iterator();
}
/**
* 代表一个集合类
*/
public interface Aggregate1{
java.util.Iterator iterator();
}
/**
* 学生类
*/
public static class Student{
private String name;
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Student{" +
"name='" + name + '\'' +
'}';
}
}
/**
* 教室迭代器
*/
public static class ClassroomIterator implements Iterator{
private Classroom classroom;
private int index;
public ClassroomIterator(Classroom classroom) {
this.classroom = classroom;
this.index = 0;
}
@Override
public boolean hasNext() {
if (index < classroom.getLength()){
return true;
}else{
return false;
}
}
@Override
public Object next() {
Student student = classroom.getStudent(index);
index++;
return student;
}
}
/**
* 教室类
*/
public static class Classroom implements Aggregate{
private Student[] students;
// last相当于数组的长度
private int last = 0;
public Classroom(int size) {
this.students = new Student[size];
}
public Student getStudent(int index) {
return students[index];
}
public void addStudent(Student student){
this.students[last] = student;
}
public int getLength(){
return last;
}
/**
* 返回一个教室迭代器,其中封装了教室自己,让迭代器可以获取教室中的数据
* @return
*/
@Override
public Iterator iterator() {
return new ClassroomIterator(this);
}
}
/**
* 教室类 1
*/
public static class Classroom1 implements Aggregate1{
private List students;
// last相当于数组的长度
private int last = 0;
public Classroom1(int size) {
this.students = new ArrayList<>(size);
}
public Student getStudent(int index) {
return students.get(index);
}
public void addStudent(Student student){
this.students.add(student);
last++;
}
public int getLength(){
return last;
}
/**
* 返回一个教室迭代器,其中封装了教室自己,让迭代器可以获取教室中的数据
* @return
*/
@Override
public java.util.Iterator iterator() {
return students.iterator();
}
}
}
4、对迭代器模式的理解
面向Iterator接口编程,无论底层的数据结构和迭代算法如何变化,调用者都不用修改代码
高内聚,低耦合,漂亮
其实一般很少自己写这个iterator模式的,一般都是在集合编程中使用,尤其是如果要对集合元素遍历过程中做插入删除操作,那就用iterator,体验JDK已经封装好的iterator模式,加深印象,如果要对某个类中的集合进行遍历,由那个集合类返回一个iterator回来,我们统一面向iterator迭代器接口来编程遍历,提高系统整体的可维护性,可扩展性
如果自己写iterator模式,一般是研发底层的框架,比如提供某个数据给外部遍历,那么可以使用iterator模式自己封装迭代器。