生活背景:
在西安讀了四年的大學,讓我印象比較深刻的是這邊的公交車,售票員吐著本地的方言這到不足為奇,可是這種方言一次次在學校的晚會上被表演時,就顯得比較逗樂了,這是一部分,還有一個我們容易忽略的是,做了這么多次公交,是不是每一次我們都必須買票呢,答案對大部分人來說是肯定的,記得又兩次次,售票員忘了讓我買票,人比較多,直到下車的時候我給她說你忘了我這張票了,塞了車費給她,然后揚長離去...
編程世界:
在很多的面向對象語言中,迭代器這個詞不在新鮮了,計算機的靈魂,數據結構和算法,這兩個讓程序員們頭疼的東西,在這些面向對象的語言中已經封裝好了。在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 元~