`
xyheqhd888
  • 浏览: 409207 次
  • 性别: Icon_minigender_1
  • 来自: 秦皇岛
社区版块
存档分类
最新评论

Iterator(迭代器)模式二

阅读更多

   CompositeIterator类的next()方法需要枚举属于某组合对象的每个子对象的节点.我们需要子类来实现iterator(:Set)方法,以便于next()代码可以使用.图2给出了这些类和接口的关系.

 

 

  为更新ProcessComponent类层次结构,以便于枚举,我们需要提供一个iterator()方法:

public ComponentIterator iterator(){
	return iterator(new HashSet());
}

public abstract ComponentIterator iterator(Set visited);

ProcessComponent类是抽象的,需要子类来实现iterator(:Set)方法.对于ProcessComposite类,其相关代码如下:

 

public ComponentIterator iterator(Set visited){
	return new CompositeIterator(this,subprocesses,visited);
}

ProcessStep对iterator()方法的实现如下:

public ComponentIterator iterator(Set visited){
	return new LeafIterator(this,visited);
}

 

突破题:如果让ProcessComponent类层次结构中的类实现iterator()方法以创建适当迭代器类的实例,请问应该使用什么设计模式?

答:  根据前面的描述,我们知道迭代器是Factory Method模式的一个很好的实例.如果用户期望为ProcessComponent类的实例创建一个迭代器,那么必须清楚何时需要创建这个迭代器.而接收类应该知道对哪个类进行实例化.

 

    除了当前对ProcessComponent类层次结构的调整之外,现在我们编写模拟过程组合结构的代码.典型的Oozinoz过程的对象模型如图4所示,如下简短代码枚举了本模型中所有节点:

 

 

package app.iterator.process;

import com.oozinoz.iterator.ComponentIterator;
import com.oozinoz.process.ProcessComponent;
import com.oozinoz.process.ShellProcess;

public class ShowProcessIteration
{
	public static void main(String[] args){
		ProcessComponent pc = ShellProcess.make();
		ComponentIterator iter = pc.iterator();
		while(iter.hasNext())
			System.out.println(iter.next());
	}
}



制作高空焰火弹的流程是一个带有环的组合结构.

该图中的每个叶节点都是ProceeStep类的实例,其余节点是ProcessComposite类的实例

 

运行本程序会得到如下结果:

  Make an aerial shell

  Build inner shell

  Inspect

  Rework inner shell, or complete shell

  Rework

  Disassemble

  Finish:Attach lift, insert fusing,wrap

输出的文本是ShellProcess类分配给每个步骤的名称.请注意在本对象模型中,disassemble步骤之后是make.没有显示出来是因为在第一行输出中已经输出这个步骤一次.

 

3.1 组合枚举器的深度:

  如果每个过程步骤加上在本模型的深度,上述代码的输出会更加容易理解.我们可以把叶枚举器的深度定义为0,组合枚举器的当前深度是子迭代器的深度加1. ComponentIterator超类中getDepth()抽象方法的定义如下:

public abstract int getDepth();

LeafIterator类使用如下代码来实现getDepth()方法:

 

public int getDepth()[
   return 0;
}

CompositeIterator.getDepth()代码实现如下所示:

public int getDepth(){
	if(subiterator != null)
		return subiterator.getDepth() + 1;  //组合枚举器的当前深度是子迭代器的当前深度加1
	return 0;
}

以下代码会产生更加容易理解的输出:

package app.iterator.process;

import com.oozinoz.iterator.ComponentIterator;
import com.oozinoz.process.ProcessComponent;
import com.oozinoz.process.ShellProcess;

public class ShowProcessIteration2
{
	public static void main(String[] args){
		ProcessComponet pc = ShellProcess.make();
		ComponentIterator iter = pc.iterator();
		while(iter.hasNext()){
			for(int i=0;i<4*iter.getDepth();i++)
				System.out.println(' ');
			System.out.println(iter.next());
		}
	}
}

上述程序的输出结果如下所示:

  Make an aerial shell

          Build inner shell

          Inspect

          Rework inner shell, or complete shell

                  Rework

                          Disassemble

                  Finish:Attach lift, insert fusing,wrap    

 

3.2. 枚举叶节点:

   假设我们希望枚举只返回叶节点.在我们只关注叶节点的属性时,这样做是很有价值的.我们可向ComponentIterator类中添加returnInterior字段,以便于记录内部(非叶子)节点是否应该从枚举处理中返回.

 

 

protected boolean returnInterior = true;

public boolean shoudShowInterior(){
	return returnInterior;
}

public void setShowInterior(boolean value){
	returnInterior = value;
}

在CompositeIterator类的nextDescendant()方法中,当为组合节点的子节点创建一个新的枚举机构时,有必要把这个属性传递下去.

protected Object nextDescendant(){
	while(true){
		if(subiterator != null){
			if(subiterator.hasNext())
				return subiterator.next();
		}

		if(!children.hasNext9)) return null;

		ProcessComonent pc = (ProcessComponent)children.next();

		if(!visited.contains(pc)){
			subiterator = pc.iterator(visited);
			subiterator.setShowInterior(shouldShowInterior());
		}
	}
}

  

我们也需要更新CompositeIterator类的next()方法,已有代码包括:

public Object next(){
    if ( peek != null){
        Object result = peek;
        peek = null;
        return  result;
    }

    if(!visited.contains(head)){
        visited.add(head);
    }

    return nextDescendant();
}

 

突破题:请更新CompositeIterator类的next()方法,以便于获取returnInterior字段的值.

答:完整的代码如下所示:

 

public Object next(){
    if ( peek != null){
        Object result = peek;
        peek = null;
        return  result;
    }

    if(!visited.contains(head)){
        visited.add(head);
        if(shouldShowInterior()) return head;
    }

    return nextDescendant();
}

为某种新的集合类型创建一个迭代器或者枚举器是项非常重要的设计任务.带来的处理是自己的集合就像Java类库中的集合类那么容易使用.

 

4.小结:

      Iterator模式的意图在于使得用户可以顺序访问集合内的元素.Java类库中的集合类为集合操作提供丰富的支持,其中也包括了对迭代或者枚举的支持.当创建一个新的集合类型时,我们通常期望能够为它创建一个迭代器.应用领域相关的组合结构是新的集合类型的一个例子.对for循环的扩展会使得代码更加清晰.可以为组合结构设计一个非常通用的迭代器,能够在各种组合结构上使用该迭代器.

      在实例化某迭代器的时候,我们应该考虑在对集合进行迭代处理的同时,集合是否会发生改变.在单线程的应用中,通常不会发生这种可能.而在多线程的应用中,我们必须首先确保对集合的访问是同步的.为保证多线程程序中迭代的安全性,可以通过锁住互斥量对象,实现对集合的同步访问.但是这种方法也有负面效果,在迭代的同时会阻塞其他所有对象对这个集合的访问;同时使用克隆集合的方法也会阻塞对该集合的访问.如果设计巧妙,我们可以为客户提供具有线程安全的迭代器代码.

  • 大小: 5.1 KB
分享到:
评论

相关推荐

    (行为型模式) Iterator 迭代器模式

    C#面向对象设计模式 (行为型模式) Iterator 迭代器模式 视频讲座下载

    Iterator迭代器讲解

    ### Iterator迭代器详解 #### 一、Iterator简介与概念 在Java编程语言中,`Iterator`接口是一个重要的组件,它提供了遍历集合的基本方法。`Iterator`的主要作用是在不暴露集合内部结构的情况下,顺序访问集合中的...

    设计模式之迭代器模式(Iterator)

    例如,在Java中,`Iterable`接口和`Iterator`接口就是实现迭代器模式的关键。`Iterable`接口定义了获取迭代器的方法`iterator()`,而`Iterator`接口提供了`hasNext()`和`next()`方法,分别用于检查是否还有下一个...

    设计模式(C#)之迭代器模式(Iterator Pattern)

    迭代器模式是软件设计模式中的一种行为模式,它在C#等面向对象编程语言中有着广泛的应用。这个模式的主要目标是允许用户遍历一个聚合对象(如数组、集合或列表)的所有元素,而无需了解底层的实现细节。下面将详细...

    java迭代器模式实现正反向遍历

    在Java编程语言中,迭代器模式(Iterator Pattern)是一种常用的设计模式,用于顺序访问集合对象中的元素,而无需暴露其底层表示。这种模式提供了一种方法来访问一个聚合对象的元素,而无需暴露该对象的内部结构。在...

    C#面向对象设计模式纵横谈(18):(行为型模式) Iterator 迭代器模式 (Level 300)

    首先,迭代器模式包含两个主要角色:聚合对象(Aggregate)和迭代器(Iterator)。聚合对象持有元素的集合,并提供创建迭代器的方法。迭代器则负责遍历聚合对象中的元素,它有一个或多个方法用于移动到下一个元素,...

    IteratorPattern 迭代设计模式

    迭代器模式(IteratorPattern)是设计模式中的一种行为模式,它提供了一种顺序访问聚合对象元素的方法,同时又不暴露其底层表示。这种模式允许我们遍历集合对象的元素,而无需暴露其内部结构。在Java、C#等面向对象...

    【Java设计模式】(1)迭代器模式Iterator

    迭代器模式(Iterator Pattern)是Java设计模式中的行为模式之一,它提供了一种方法来顺序访问聚合对象的元素,而又不暴露其底层表示。在Java中,迭代器模式被广泛应用于集合类,如ArrayList、LinkedList等,通过...

    C#面向对象设计模式纵横谈\18 行为型模式Iterator迭代器模式.zip

    在这里与各位分享本人从网络上下载的C#面向对象设计模式纵横谈系列视频,共有25节,除了第一节需要各位贡献一点资源分以作为对本人上传资源的回馈,后面的其他资源均不... 这是第18节:行为型模式Iterator迭代器模式

    迭代器模式代码示例

    迭代器模式是一种设计模式,属于行为设计模式,它允许我们顺序访问聚合对象的元素,而无需暴露其底层表示。在Java、C#等面向对象语言中,迭代器模式被广泛应用于容器类,如ArrayList、LinkedList等,使得我们可以...

    23钟设计模式之迭代器模式模式

    2. **解耦**:迭代器模式通过引入迭代器角色,将聚合对象和遍历算法分离,降低两者之间的耦合度。 3. **灵活性与可扩展性**:迭代器模式支持在不改变聚合类及其客户端的情况下,提供新的迭代器类,增加新的遍历方式...

    迭代器模式Demo

    迭代器模式是一种设计模式,它在软件工程中扮演着重要的角色,特别是在处理集合或容器类对象的遍历操作时。这种模式提供了一种方法来顺序访问聚合对象的元素,而无需暴露其底层表示。在Java、C#等面向对象语言中,...

    设计模式的迭代器模式的例子

    迭代器模式是软件设计模式中的一种行为模式,它允许我们顺序访问聚合对象的元素,而无需暴露其底层表示。在Java、C#等面向对象语言中,迭代器模式被广泛应用于容器类,如ArrayList、LinkedList等,使得我们可以方便...

    设计模式之迭代器模式

    迭代器模式是一种行为设计模式,它提供了一种方法来顺序访问聚合对象的元素,而无需暴露其底层表示。在Java中,迭代器模式是通过接口实现的,这使得我们可以遍历任何实现了`Iterable`接口的对象,例如集合框架中的`...

    设计模式C++学习之迭代器模式(Iterator)

    迭代器模式是软件设计模式中的行为模式之一,它在C++编程中有着广泛的应用。这个模式提供了一种方法来顺序访问聚合对象的元素,而无需暴露其底层表示。通过迭代器,用户可以遍历集合中的所有元素,而无需知道如何...

    迭代器模式(Iterator Pattern)原理图

    迭代器模式(Iterator Pattern)是设计模式中的一种行为模式,它允许顺序访问一个聚合对象中的各个元素,而又不需要暴露该对象的内部表示。迭代器模式提供了一种方法,可以顺序地访问一个聚合对象中的各个元素,而又...

    设计模式-迭代器模式(讲解及其实现代码)

    在Java、C#等面向对象语言中,迭代器模式的应用非常广泛,例如Java中的`Iterable`接口和`Iterator`接口,C#中的`IEnumerable`接口和`IEnumerator`接口。这些接口为实现迭代器模式提供了标准的方式。 迭代器模式的...

Global site tag (gtag.js) - Google Analytics