迭代模式在日常的应用中几乎是无处不在,但是因为Java内部已经实现对集合对象的迭代,所以好像这种模式不常用,其实是用到了,只是没觉察到,今天就在这里剖析其中的秘密。
先看看迭代模式的类图:
关于迭代模式:
迭代模式提供了一种不暴漏集合对象的内部结构,又可以迭代该集合的方法,
关于迭代模式分离的集合对象的遍历行为,抽象出一个迭代类负责遍历,这样就做到了
不暴漏集合对象的内部结构,可以让外部代码透明的访问集合对象内部。
结构:
一个抽象的迭代类,定义了抽象的迭代方法;
一个抽象迭代类的子类,覆盖了父类的所有抽象迭代方法
该子类依赖聚集类的子类
一个抽象的聚集类,定义了创建的迭代类的抽象方法
一个抽象聚集类的子类,覆盖了父类的所有的抽象方法
该子类关联迭代类的子类
根据上面的描述,接下来看代码:
抽象的迭代类:
抽象迭代类的子类
抽象聚集类
抽象聚集类的子类
客户端代码
运行结果:
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
先看看迭代模式的类图:
关于迭代模式:
迭代模式提供了一种不暴漏集合对象的内部结构,又可以迭代该集合的方法,
关于迭代模式分离的集合对象的遍历行为,抽象出一个迭代类负责遍历,这样就做到了
不暴漏集合对象的内部结构,可以让外部代码透明的访问集合对象内部。
结构:
一个抽象的迭代类,定义了抽象的迭代方法;
一个抽象迭代类的子类,覆盖了父类的所有抽象迭代方法
该子类依赖聚集类的子类
一个抽象的聚集类,定义了创建的迭代类的抽象方法
一个抽象聚集类的子类,覆盖了父类的所有的抽象方法
该子类关联迭代类的子类
根据上面的描述,接下来看代码:
抽象的迭代类:
- //创建抽象的迭代类,定了的抽象的迭代方法
- 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