1、iterator 模式
需求:給大家舉個例子,現(xiàn)在假設(shè),有一個教室類,里面包含了一堆學(xué)生,我現(xiàn)在要遍歷教室里的學(xué)生,怎么來玩
2、不使用設(shè)計(jì)模式的代碼
/**
* 不用模式實(shí)現(xiàn)
*/
public class WithoutIteratorPatternDemo {
/**
* 如果不用任何設(shè)計(jì)模式,直接去遍歷一個類中的集合
* 一旦這個類中對集合的使用改版了,比如從數(shù)組 —> map ,還有別的可能
* 你迭代的這塊功能,就要改動
* 如果說迭代和業(yè)務(wù)邏輯和復(fù)雜,同時集合類的實(shí)現(xiàn)和遍歷代碼的實(shí)現(xiàn),是兩個人開發(fā)的
* 成本就很高了,大家有要協(xié)調(diào),又要改動
* 簡單來說,這種代碼,可擴(kuò)展性,可維護(hù)性很差,就是屎一樣的代碼
* @param args
*/
public static void main(String[] args) {
}
/**
* 從之前的數(shù)組換成 hashmap 之后,發(fā)現(xiàn)我們的遍歷方法又需要改變了
*/
private static void method2() {
Student student1 = new Student("小明");
Student student2 = new Student("小王");
HashMap<String, Student> students = new HashMap<>();
students.put(student1.getName(), student1);
students.put(student2.getName(), student2);
ClassRoom1 classRoom1 = new ClassRoom1();
classRoom1.setStudents(students);
HashMap<String, Student> resultStudents = classRoom1.getStudents();
for (Student student : resultStudents.values()) {
System.out.println(student);
}
}
/**
* 數(shù)組的時候遍歷集合
*/
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);
//現(xiàn)在要遍歷教室中的學(xué)生
Student[] resultStudents = classRoom.getStudents();
for (Student resultStudent : resultStudents) {
System.out.println(resultStudent);
}
}
/**
* 學(xué)生類
*/
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<String, Student> students;
public HashMap<String, Student> getStudents() {
return students;
}
public void setStudents(HashMap<String, Student> students) {
this.students = students;
}
}
}
3、用迭代器模式的時候
/**
* 用迭代器模式的實(shí)現(xiàn)
*/
public class IteratorPatternDemo {
public static void main(String[] args) {
// 數(shù)組的時候
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();
}
/**
* 學(xué)生類
*/
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相當(dāng)于數(shù)組的長度
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;
}
/**
* 返回一個教室迭代器,其中封裝了教室自己,讓迭代器可以獲取教室中的數(shù)據(jù)
* @return
*/
@Override
public Iterator iterator() {
return new ClassroomIterator(this);
}
}
/**
* 教室類 1
*/
public static class Classroom1 implements Aggregate1{
private List<Student> students;
// last相當(dāng)于數(shù)組的長度
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;
}
/**
* 返回一個教室迭代器,其中封裝了教室自己,讓迭代器可以獲取教室中的數(shù)據(jù)
* @return
*/
@Override
public java.util.Iterator iterator() {
return students.iterator();
}
}
}
4、對迭代器模式的理解
面向Iterator接口編程,無論底層的數(shù)據(jù)結(jié)構(gòu)和迭代算法如何變化,調(diào)用者都不用修改代碼
高內(nèi)聚,低耦合,漂亮
其實(shí)一般很少自己寫這個iterator模式的,一般都是在集合編程中使用,尤其是如果要對集合元素遍歷過程中做插入刪除操作,那就用iterator,體驗(yàn)JDK已經(jīng)封裝好的iterator模式,加深印象,如果要對某個類中的集合進(jìn)行遍歷,由那個集合類返回一個iterator回來,我們統(tǒng)一面向iterator迭代器接口來編程遍歷,提高系統(tǒng)整體的可維護(hù)性,可擴(kuò)展性
如果自己寫iterator模式,一般是研發(fā)底層的框架,比如提供某個數(shù)據(jù)給外部遍歷,那么可以使用iterator模式自己封裝迭代器。