流殃的博客

| Comments

不使用迭代器模式

package com.zhss.designpattern.iterator;

import java.util.HashMap;
import java.util.Map;
public class WithoutIteratorPatternDemo {
	
	public static void main(String[] args) {
		Student student1 = new Student("小明");
		Student student2 = new Student("小王");
		
//		Student[] students = new Student[2];
//		students[0] = student1;
//		students[1] = student2;
		
		Map<String, Student> students = new HashMap<String, Student>();
		students.put(student1.getName(), student1);
		students.put(student2.getName(), student2);
		
		Classroom classroom = new Classroom();
		classroom.setStudents(students);  
		
//		Student[] resultStudents = classroom.getStudents();
//		for(Student resultStudent: resultStudents) {
//			System.out.println(resultStudent);  
//		}
		
		Map<String, Student> resultStudents = classroom.getStudents();
		for(Student resultStudent : resultStudents.values()) {
			System.out.println(resultStudent); 
		}
		
		// 如果不用任何设计模式,直接去遍历一个类中的集合
		// 一旦这个类中对集合的使用改版了,比如从数组 -> map,还有别的可能
		// 你迭代的这块代码,就要改动
		// 如果说代码和业务逻辑很复杂,同时集合类的实现和遍历代码的实现,是两个人开发的
		// 成本就很高了,大家又要协调,又要改动
		// 简单来说,这种代码,可扩展性,可维护性,很差。屎一样的代码
	}

	/**
	 * 学生类
	 * @author zhonghuashishan
	 *
	 */
	public static class Student {
		
		private String name;

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

		public String getName() {
			return name;
		}

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

		@Override
		public String toString() {
			return "Student [name=" + name + "]";
		}
		
	}

//	/**
//	 * 教室类
//	 * @author zhonghuashishan
//	 *
//	 */
//	public static class Classroom {
//		
//		private Student[] students;
//
//		public Student[] getStudents() {
//			return students;
//		}
//
//		public void setStudents(Student[] students) {
//			this.students = students;
//		}
//		
//	}
	
	/**
	 * 教室类
	 * @author zhonghuashishan
	 *
	 */
	public static class Classroom {
		
		private Map<String, Student> students;

		public Map<String, Student> getStudents() {
			return students;
		}

		public void setStudents(Map<String, Student> students) {
			this.students = students;
		}
		
	}
	
}

使用迭代器模式

package com.zhss.designpattern.iterator;

import java.util.ArrayList;
import java.util.List;
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);  
		
		java.util.Iterator<Student> iterator = classroom.iterator();
		while(iterator.hasNext()) {  
			Student student = (Student) iterator.next();
			System.out.println(student);  
		}
	}

	/**
	 * 定义一个我们自己的迭代器接口
	 * @author zhonghuashishan
	 *
	 */
	public interface Iterator {
	    
	    public abstract boolean hasNext();
	    public abstract Object next();
	    
	}
	
	/**
	 * 代表了一个集合类
	 * @author zhonghuashishan
	 *
	 */
	public interface Aggregate {
	    
	    public abstract java.util.Iterator<Student> iterator();
	     
	}
	
	/**
	 * 学生类
	 * @author zhonghuashishan
	 *
	 */
	public static class Student {
	    
	    private String name;
	    
	    public Student(String name) {
	        this.name = name;
	    }
	    
	    public String getName() {
	        return name;
	    }

		@Override
		public String toString() {
			return "Student [name=" + name + "]";
		}
	    
	}
	
	/**
	 * 教室迭代器
	 * @author zhonghuashishan
	 *
	 */
	public static class ClassroomIterator implements Iterator {
	    
	    private Classroom classroom;
	    private int index;
	    
	    public ClassroomIterator(Classroom classroom) {
	        this.classroom = classroom;
	        this.index = 0;
	    }
	    
	    /**
	     * 假设此时index是0,classroom的length是2
	     * 那么肯定是可以去获取下一个学生的,此时数组还没遍历完
	     * 
	     * 假设此时index是2,classroom的length是2,classroom可以遍历的数组的offset只能是0和1
	     */
	    public boolean hasNext() {
	        if(index < classroom.getLength()) {
	            return true;
	        } else {
	            return false;
	        }
	    }
	    
	    /**
	     * 从数组中获取当前的这个学生,同时将index往下移动一位
	     * 比如一开始index是0,然后数组长度是2
	     * 此时遍历获取了第一个学生之后,返回了数组的0元素,然后将index变为1了
	     */
	    public Object next() {
	        Student student = classroom.getStudent(index);
	        index++;
	        return student;
	    }
	    
	}
	
	/**
	 * 教室类
	 * @author zhonghuashishan
	 *
	 */
	public static class Classroom implements Aggregate {
	    
//	    private Student[] students;
		
		private List<Student> students;
	    
	    /**
	     * last相当于是数组的长度
	     */
	    private int last = 0;
	    
	    public Classroom(int size) {
//	        this.students = new Student[size];
	    	this.students = new ArrayList<Student>(2);
	    }
	    
	    public Student getStudent(int index) {
//	        return students[index];
	    	return students.get(index);
	    }
	    
	    public void addStudent(Student student) {
//	        this.students[last] = student;
	    	this.students.add(student);
	        last++;
	    }
	    
	    public int getLength() {
	        return last;
	    }
	    
	    /**
	     * 返回一个教室迭代器,其中封装了教室自己,让迭代器可以获取教室中的数据
	     */
	    public java.util.Iterator<Student> iterator() { 
//	        return new ClassroomIterator(this);
	    	return students.iterator();
	    }
	    
	}
	
}

总结

优点: 不论底层的数据结构和迭代算法如何变化,调用者都不需要修改代码
高内聚,低耦合
但是其实在生产过程中,一般来说,自己很少写这个iterator模式的,一般都是在集合编程中使用,尤其是如果对集合元素遍历的过程中做插入和删除操作,那就用iterator。
如果自己写的话,一般是研发底层的框架,比如低筒某个数据给外部遍历,那可以使用iterator模式自己来封装迭代器

Comments

评论