迭代模式在日常的应用中几乎是无处不在,但是因为Java内部已经实现对集合对象的迭代,所以好像这种模式不常用,其实是用到了,只是没觉察到,今天就在这里剖析其中的秘密。
先看看迭代模式的类图:
[img]http://dl.iteye.com/upload/attachment/483777/325ed751-855e-31ec-b253-5fcff893faaa.jpg[/img]
关于迭代模式:
迭代模式提供了一种不暴漏集合对象的内部结构,又可以迭代该集合的方法,
关于迭代模式分离的集合对象的遍历行为,抽象出一个迭代类负责遍历,这样就做到了
不暴漏集合对象的内部结构,可以让外部代码透明的访问集合对象内部。
结构:
一个抽象的迭代类,定义了抽象的迭代方法;
一个抽象迭代类的子类,覆盖了父类的所有抽象迭代方法
该子类依赖聚集类的子类
一个抽象的聚集类,定义了创建的迭代类的抽象方法
一个抽象聚集类的子类,覆盖了父类的所有的抽象方法
该子类关联迭代类的子类
根据上面的描述,接下来看代码:
抽象的迭代类:
抽象迭代类的子类
抽象聚集类
抽象聚集类的子类
客户端代码
运行结果:
AAAA
BBBB
CCCC
DDDD
在回到上面的图中,在这个类图中可以看出:
迭代器类继承了抽象的迭代器
聚集类继承了抽象的父类,
但是ConcreteIterator和ConcreteAggregate是关联关系,
而 ConcreteAggregate和ConcreteIterator是依赖关系。
一点题外话:
这里有必要说明一下关联和依赖的区别,这两个概念其实很容易混淆
依赖是一个弱得关联,如果一个类A依赖一个类B,那么在A中B有3中用法:
B是全局的
B被实例化
B被作为参数传递
关联代表一种结构化的关系,表现为一个对象能获得另一个对象的实例引用并且调用它的服务,
依赖则是调用了一个对象的服务
关联还有单双向之分,双向关联,AB两个类,如果双向关联,则互为对方的Attribue,单向关联就是一个是另一个的Attribute
依赖则只有单向的
在ConcreteIterator中存在
因此ConcreteAggregate 是ConcreteIterator的属性,属于关联关系
在ConcreteAggregate中存在
ConcreteIterator 被实例化了,因此ConcreteAggregate 依赖 ConcreteAggregate
先看看迭代模式的类图:
[img]http://dl.iteye.com/upload/attachment/483777/325ed751-855e-31ec-b253-5fcff893faaa.jpg[/img]
关于迭代模式:
迭代模式提供了一种不暴漏集合对象的内部结构,又可以迭代该集合的方法,
关于迭代模式分离的集合对象的遍历行为,抽象出一个迭代类负责遍历,这样就做到了
不暴漏集合对象的内部结构,可以让外部代码透明的访问集合对象内部。
结构:
一个抽象的迭代类,定义了抽象的迭代方法;
一个抽象迭代类的子类,覆盖了父类的所有抽象迭代方法
该子类依赖聚集类的子类
一个抽象的聚集类,定义了创建的迭代类的抽象方法
一个抽象聚集类的子类,覆盖了父类的所有的抽象方法
该子类关联迭代类的子类
根据上面的描述,接下来看代码:
抽象的迭代类:
//创建抽象的迭代类,定了的抽象的迭代方法
public abstract class Iterator {
public abstract String First();
public abstract String Next();
public abstract boolean IsDone();
public abstract String CurrentItem();
}
抽象迭代类的子类
//创建具体的迭代类,需要关联具体的聚集类
public class ConcreteIterator extends Iterator {
private ConcreteAggregate aggregate;
private int index=0;
//定义迭代器的构造方法,使用一个聚集类作为入口参数
public ConcreteIterator(ConcreteAggregate aggregate){
this.aggregate = aggregate;
}
//覆盖了父类的所有的抽象方法
@Override
public String CurrentItem() {
return aggregate.getItem(index);
}
@Override
public String First() {
return aggregate.getItem(0);
}
@Override
public String Next() {
String ret="";
if (!IsDone()){
ret = aggregate.getItem(index);
index +=1 ;
}
return ret;
}
@Override
public boolean IsDone() {
boolean ret;
if (index >= aggregate.getCount()){
ret = true;
}else{
ret = false;
}
return ret;
}
}
抽象聚集类
//创建抽象的聚集类
public abstract class Aggregate {
public abstract Iterator CreateIterator();
}
抽象聚集类的子类
//创建具体的聚集类,该类依赖ConcreteAggregate
public class ConcreteAggregate extends Aggregate{
private List<String> items = new ArrayList<String>();
@Override
public Iterator CreateIterator() {
return new ConcreteIterator(this);
}
public int getCount(){
return items.size();
}
public String getItem(int index){
return items.get(index);
}
public void setItem(String msg){
items.add(msg);
}
}
客户端代码
public class Test {
public static void main(String[] args) {
//创建一个集合对象
ConcreteAggregate aggregate = new ConcreteAggregate();
aggregate.setItem("AAAA");
aggregate.setItem("BBBB");
aggregate.setItem("CCCC");
aggregate.setItem("DDDD");
//创建一个该集合的迭代器,把集合作为参数传入
Iterator i = new ConcreteIterator(aggregate);
String x;
while(!i.IsDone()){
x = i.Next();
putln(x);
}
}
public static void putln(Object o){
System.out.println(o);
}
}
运行结果:
AAAA
BBBB
CCCC
DDDD
在回到上面的图中,在这个类图中可以看出:
迭代器类继承了抽象的迭代器
聚集类继承了抽象的父类,
但是ConcreteIterator和ConcreteAggregate是关联关系,
而 ConcreteAggregate和ConcreteIterator是依赖关系。
一点题外话:
这里有必要说明一下关联和依赖的区别,这两个概念其实很容易混淆
依赖是一个弱得关联,如果一个类A依赖一个类B,那么在A中B有3中用法:
B是全局的
B被实例化
B被作为参数传递
关联代表一种结构化的关系,表现为一个对象能获得另一个对象的实例引用并且调用它的服务,
依赖则是调用了一个对象的服务
关联还有单双向之分,双向关联,AB两个类,如果双向关联,则互为对方的Attribue,单向关联就是一个是另一个的Attribute
依赖则只有单向的
在ConcreteIterator中存在
ConcreteAggregate aggregate;
因此ConcreteAggregate 是ConcreteIterator的属性,属于关联关系
在ConcreteAggregate中存在
new ConcreteIterator(this);
ConcreteIterator 被实例化了,因此ConcreteAggregate 依赖 ConcreteAggregate