编程世界:
在很多的面向对象语言中,迭代器这个词不在新鲜了,计算机的灵魂,数据结构和算法,这两个让程序员们头疼的东西,在这些面向对象的语言中已经封装好了。在
Java中JDK1.5以后的版本中,有个foreach,增强for循环,里面用的就是迭代器的原理,当然这个迭代器比较简单,是按顺序从头到尾取出一个集合中的元素,让我们这些程序员简化了很多的操作。在Java中集合类中,如List,Set,Map等,都可以用迭代器取出这些集合中的元素。
故事背景:
如今流行穿越,21实际又逢赤壁之战,刘备带领着几名心腹赴赤壁与东吴会合,准备与枭雄曹操一决高下,当然如今的交通发达,再也不用骑马那种比较慢且耗体力的交通了,这时,他们来到路边,等待着公交车的到来,十分钟后,一辆公交车缓缓驰来,他们上车了...
设计模式:
迭代器:提供一种方法顺序地访问一个聚合对象中的各个元素,而又不暴露该对象的内部表示。
面向对象的分析:
1.抽取对象:聚合对象,这里是公交车,是一个具体的,当然集合对象不限于公交车,所以可以抽取一个抽象类:
聚合抽象类:Aggragate
具体聚合类:Bus
聚合对象中的乘客:Passenger
迭代器对象:在这个需求中,迭代器是售票员,同样也抽取一个抽象的迭代器,因为迭代器的迭代顺序可以不一致:
抽象迭代器:Iterator
具体的迭代器:Conductor
2.类的职责:Aggregate提供一个创建迭代器的行为,在Bus中有Passenger,所以要提供当前乘客的数量的行为,还有上下车的行为,即加或减乘客
Aggregate:iterator();
Bus:removePassenger();addPassenger();count();getPassenger(int index);
Iterator:既然是迭代器,就会提供如下行为:first();next();hasNext();current();
3.类的交互:在具体的聚合类Bus中显然装的是乘客,然而迭代器要迭代聚合对象的元素,即必须依赖了聚合对象。
UML类图:
代码实现:
Iterator抽象类:
[java]
public abstract class Iterator {
/**
* 获取集合的第一个元素
* @return 返回集合的第一个元素
*/
public abstract Object first();
/**
* 获取集合的下一个元素
* @return 返回集合的下一个元素
*/
public abstract Object next();
/**
* 判断是否还有下一个元素
* @return 如果有 返回true 反之返回flase
*/
public abstract boolean hasNext();
/**
* 获取集合当前的元素
* @return
*/
public abstract Object current();
}
@这个迭代器类就提供了几个行为,可以用interface表示,因为任何不相关的类获取都有迭代的功能;
Aggregate抽象聚合类:
[java]
/**
* 聚合的抽象类
*
* @author PingCX
*
*/
public abstract class Aggregate {
/**
* 聚合对象自身负责创建一个迭代器
*
* @return
*/
public abstract Iterator iterator();
}
@这里只提供了一个创建Iterator的接口;
Bus具体的聚合类:
[java]
public class Bus extends Aggregate {
/**
* 集合对象中包含了乘客,这里讲售票员不计入
*/
private List<Passenger> passengers = new ArrayList<Passenger>();
/**
* 添加乘客,即有乘客上车
* @param passenger
*/
public void addPassenger(Passenger passenger){
passengers.add(passenger);
}
/**
* 移除乘客,即乘客下车,这里假设先上的先下
*/
public void removePassenger(){
passengers.remove(0);
}
/**
* 获取总个数
* @return 返回总个数
*/
public int count(){
return passengers.size();
}
/**
* 根据下标返回一个乘客对象
* @param index
* @return
*/
public Passenger getPassenger(int index){
return passengers.get(index);
}
@Override
public Iterator iterator() {
return new Conductor(this);
}
}
@在这个具体的聚合类Bus中是要上乘客的;
@那个Passenger是乘客类:
[java]
public class Passenger {
private String name;
public Passenger(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Override
public String toString() {
return "Passenger [name=" + name + "]";
}
}
然后看我们的核心迭代器售票员Conductor了:
[java]
/**
* 售票员,具体的迭代器
*
* @author PingCX
*
*/
public class Conductor extends Iterator {
private Bus bus; // 具体的聚合对象
private int current; //记录当前位置
public Conductor(Bus bus) {
this.bus = bus;
}
@Override
public Object first() {
return bus.getPassenger(0);
}
@Override
public Object next() {
if (current >= bus.count()) {
return null;
}
return bus.getPassenger(current++);
}
@Override
public boolean hasNext() {
return current < bus.count() ? true : false;
}
@Override
public Object current() {
return bus.getPassenger(current);
}
}
然后就是刘备带着心腹在等公交,也就是我们测试:
[java]
public class Client {
public static void main(String[] args) {
//刘备,张飞,关羽和赵云在等公交车
Passenger p1 = new Passenger("刘备");
Passenger p2 = new Passenger("张飞");
Passenger p3 = new Passenger("关羽");
Passenger p4 = new Passenger("赵云");
Passenger p5 = new Passenger("诸葛亮");
//来了一辆公交车
Bus bus = new Bus();
bus.addPassenger(p1);
bus.addPassenger(p2);
bus.addPassenger(p3);
bus.addPassenger(p4);
bus.addPassenger(p5);
//公交车的售票员出马了
Iterator it = bus.iterator();
while(it.hasNext()){
String name = ((Passenger)it.next()).getName();
System.out.println("售票员:" + name + ",请买票!");
System.out.println(name + " : 赤壁下...");
System.out.println("售票员:1 元~");
}
}
}
@打印的结果:
售票员:刘备,请买票!
刘备 : 赤壁下...
售票员:1 元~
售票员:张飞,请买票!
张飞 : 赤壁下...
售票员:1 元~
售票员:关羽,请买票!
关羽 : 赤壁下...
售票员:1 元~
售票员:赵云,请买票!
赵云 : 赤壁下...
售票员:1 元~
售票员:诸葛亮,请买票!
诸葛亮 : 赤壁下...
售票员:1 元~