迭代子模式可以順序的訪問集合內(nèi)部的元素而不必知道集合內(nèi)部表象帆精。
多個對象聚集在一起形成集合的概念叉弦,所以集合對象也叫容器川尖,包含 n 多對象的池子一樣登下。集合對象需要提供一些方法,使得可以順序訪問內(nèi)部對象叮喳。集合對象常見的問題分為兩類被芳,一是把一種集合對象轉(zhuǎn)換為另外一個集合對象,由于集合對象各自的遍歷集合不同馍悟,這里就需要修改客戶端代碼了(違背開閉原則)畔濒;二是集合本身不變,迭代方法改變锣咒,這個時候需要修改集合對象侵状。這兩個問題都涉及到需要修改代碼,也就違背了開閉原則(能夠在不修改代碼的情況下對功能進(jìn)行擴(kuò)展毅整,開閉原則其實(shí)是需要把不變的與易變的進(jìn)行分割
)趣兄。針對這樣的問題,在客戶端和集合對象之間增加一個迭代子這么一個中間層悼嫉,使得客戶端和集合對象之間由直接變成間接艇潭,降低耦合力度。
迭代子模式的類圖大概如下所示
Aggregate集合:創(chuàng)建迭代子的接口;
ConcreteAggregate 具體集合:實(shí)現(xiàn)迭代子接口蹋凝;
Iterator 迭代子接口:給出迭代每個元素的接口鲁纠;
ConcreteIterator 具體迭代子:實(shí)現(xiàn)迭代方法。
如果一個集合對象對外提供了修改內(nèi)部元素的方法鳍寂,那么這個接口就叫寬接口
改含;如果不對外提供修改元素的方法,就叫窄接口
,其實(shí)這叫法我覺得無所謂迄汛,關(guān)鍵是集合類對外提供修改接口捍壤,就破壞了集合對象的封裝,而此時的迭代子在外部控制元素的迭代隔心,作用相當(dāng)于一個游標(biāo),有個雅稱叫游標(biāo)迭代子
尚胞;改良的做法是集合對象對外不提供對元素的修改方法硬霍,只對迭代子提供寬接口。
下面使用代碼更加形象的說明之笼裳。
集合類提供幾個方法唯卖,第一個是獲取迭代子;第二個是獲得指定位置的元素了第三是獲取集合元素的數(shù)量躬柬;
public abstract class Aggregate {
public abstract MyIterator iterator();
public abstract Object getElement(int index);
public abstract int size();
}
具體集合類的實(shí)現(xiàn),這里使用一個數(shù)組作為靜態(tài)的內(nèi)部元素拜轨,如果使用動態(tài)外部的元素需要改造
public class ConcreteAggregate extends Aggregate{
private String[]arr={"A","B","C"};
@Override
public MyIterator iterator() {
return new ConcreteIterator(this);
}
public Object getElement(int index){
return arr[index];
}
public int size(){
return arr.length;
}
}
抽象迭代子
public interface MyIterator {
//移動到第一個對象
public void first();
//是否最后
public boolean isLast();
//移動下一個
public void next();
//當(dāng)前對象
public Object current();
}
一個具體的實(shí)現(xiàn)
public class ConcreteIterator implements MyIterator{
Aggregate agg;
int size=0;
int index=0;
public ConcreteIterator(Aggregate agg) {
this.agg=agg;
size=agg.size();
}
@Override
public void first() {
index=0;
}
@Override
public boolean isLast() {
return index>=size;
}
@Override
public void next() {
if(index<size){
index++;
}
}
@Override
public Object current() {
return agg.getElement(index);
}
}
來個客戶端運(yùn)行下看看
public class Client {
public static void main(String[] args) {
Aggregate agg=new ConcreteAggregate();
MyIterator iterator = agg.iterator();
//可以把 isLast 和 next 方法整合到一起
while(!iterator.isLast()){
System.out.println(iterator.current());
iterator.next();
}
}
}
可以打印出A、B允青、C橄碾,而且可以新增新的迭代子和新的集合類實(shí)現(xiàn)來進(jìn)行不同的順序輸出。
迭代子模式的意義是使得客戶端與迭代子任務(wù)分開颠锉,使二者各自完成自己的主要工作法牲,在集合對象發(fā)生改變或者迭代方法發(fā)生變化的時候,有了這個迭代子緩沖地帶琼掠,我們可以盡量只對迭代子部分進(jìn)行修改拒垃。并不是說客戶端自己不可以迭代,只是不夠優(yōu)雅瓷蛙。
迭代子把集合的循環(huán)迭代方法進(jìn)行了處理悼瓮,集合本身不需要迭代;集合本身可以包含不僅一個的迭代子艰猬,根據(jù)情況獲取不同的迭代子横堡,進(jìn)行不同的迭代子處理;遍歷算法包括迭代子內(nèi)部冠桃,因此迭代子獨(dú)立于集合翅萤。迭代子的缺點(diǎn)是對象總是 Object 的,這個需要顯示的強(qiáng)制轉(zhuǎn)換。