设计模式之迭代模式

场景:

当一个聚集对象需要被遍历,且被遍历的方式需要与聚集对象解耦的情况下,迭代器模式是不二之选。由于java语言本身带有众多集合类,如List、Set、Map等,这些集合内部都有迭代器,所以迭代模式很少用,除非自己定义一个容器。

特点:

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

实际就是封装一个自己的集合迭代器

示例场景

有一个教室类,里面包含了一堆学生,现在要遍历教室里的学生信息。

未使用迭代模式时

public class NoIteratorPattern {

public static void main(String[] args) {
Classroom classroom = new Classroom();

Student student1 = new Student("张三");
classroom.addStudent(student1);

Student student2 = new Student("李四");
classroom.addStudent(student2);

List students = classroom.getStudents();
for(Student student : students) {
System.out.println(student);
}
}

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 Classroom {

private final List students;

public Classroom(){
this.students = new ArrayList<>();
}

public List getStudents() {
return students;
}

public void addStudent(Student students){
this.students.add(students);
}

}
}

此时如果需要改为数组和迭代器的实现,同时业务逻辑复杂的话,则调用者也需要改动自己的代码,这样的维护性差。

使用迭代模式

public class IteratorPattern {

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);

Iterator iterator = classroom.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}

public interface Iterator{

/**
* 是否有下一个
* @return 返回结果
*/
boolean hasNext();

/**
* 获取下一个
* @return 返回下一个
*/
T next();
}

public interface Aggregate{
/**
* 迭代器
* @return 返回一个迭代器
*/
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 Classroom implements Aggregate {

private final List students;

private int last = 0;

public Classroom(int size){
students = new ArrayList<>();
}

public Student getStudent(int index){
return this.students.get(index);
}

public void addStudent(Student student){
this.students.add(student);
last++;
}

public int getLast() {
return last;
}

@Override
public Iterator iterator() {
return new ClassroomIterator(this);
}
}

public static class ClassroomIterator implements Iterator{

private final Classroom classroom;

private int index;

public ClassroomIterator(Classroom classroom){
this.classroom = classroom;
this.index = 0;
}

@Override
public boolean hasNext() {
return this.index<this.classroom.getLast();
}

@Override
public Student next() {
Student student = this.classroom.getStudent(index);
this.index++;
return student;
}
}
}

使用迭代模式后,当我们需要更改内部实现时,调用者几乎不用修改自己的代码即可使用。

posted @ 2020-08-08 17:10  起岸星辰  阅读(281)  评论(0)    收藏  举报