迭代模式是行为模式之一,它把对容器中包含的内部对象的访问委让给外部类,使用Iterator(遍历)按顺序进行遍历访问的设计模式。
在应用Iterator模式之前,首先应该明白Iterator模式用来解决什么问题。或者说,如果不使用Iterator模式,会存在什么问题。
1.由容器自己实现顺序遍历。直接在容器类里直接添加顺序遍历方法
2.让调用者自己实现遍历。直接暴露数据细节给外部。
以上方法1与方法2都可以实现对遍历,这样就会出现一些问题如:
1,容器类承担了太多功能:一方面需要提供添加删除等本身应有的功能;一方面还需要提供遍历访问功能。
2,往往容器在实现遍历的过程中,需要保存遍历状态,当跟元素的添加删除等功能夹杂在一起,很容易引起混乱和程序运行错误等。
让我们通过一个简单的例子来理解迭代器模式。假设我们有一个无线电信道列表,并且客户端程序希望逐个或基于信道类型遍历它们。例如,一些客户端程序仅对英语频道感兴趣并且想要仅处理它们,他们不想处理其他类型的频道。
因此,我们可以向客户端提供一组通道,让他们编写逻辑来遍历通道并决定是否处理它们。但是这个解决方案有很多问题,比如客户端必须提出遍历的逻辑。我们无法确保客户端逻辑是正确的。此外,如果客户端数量增加,那么维护将变得非常困难。
在这里,我们可以使用Iterator模式并根据通道类型提供迭代。我们应该确保客户端程序只能通过迭代器访问通道列表。
实现的第一部分是为我们的集合和迭代器接口定义合同。
package com.journaldev.design.iterator; public enum ChannelTypeEnum { ENGLISH, HINDI, FRENCH, ALL; }
Channel是一个简单的POJO类,具有属性频率和通道类型。
package com.journaldev.design.iterator; public class Channel { private double frequency; private ChannelTypeEnum TYPE; public Channel(double freq, ChannelTypeEnum type){ this.frequency=freq; this.TYPE=type; } public double getFrequency() { return frequency; } public ChannelTypeEnum getTYPE() { return TYPE; } @Override public String toString(){ return "Frequency="+this.frequency+", Type="+this.TYPE; } }
ChannelCollection接口定义了我们的集合类实现的契约:
package com.journaldev.design.iterator; public interface ChannelCollection { public void addChannel(Channel c); public void removeChannel(Channel c); public ChannelIterator iterator(ChannelTypeEnum type); }
package com.journaldev.design.iterator; public interface ChannelIterator { public boolean hasNext(); public Channel next(); }
现在我们的基本接口和核心类已准备就绪,让我们继续执行集合类和迭代器。
package com.journaldev.design.iterator; import java.util.ArrayList; import java.util.List; public class ChannelCollectionImpl implements ChannelCollection { private List<Channel> channelsList; public ChannelCollectionImpl() { channelsList = new ArrayList<>(); } public void addChannel(Channel c) { this.channelsList.add(c); } public void removeChannel(Channel c) { this.channelsList.remove(c); } @Override public ChannelIterator iterator(ChannelTypeEnum type) { return new ChannelIteratorImpl(type, this.channelsList); } private class ChannelIteratorImpl implements ChannelIterator { private ChannelTypeEnum type; private List<Channel> channels; private int position; public ChannelIteratorImpl(ChannelTypeEnum ty, List<Channel> channelsList) { this.type = ty; this.channels = channelsList; } @Override public boolean hasNext() { while (position < channels.size()) { Channel c = channels.get(position); if (c.getTYPE().equals(type) || type.equals(ChannelTypeEnum.ALL)) { return true; } else position++; } return false; } @Override public Channel next() { Channel c = channels.get(position); position++; return c; } } }
请注意迭代器接口的内部类实现,以便任何其他集合都不能使用该实现。同样的方法之后是集合类,它们都具有Iterator接口的内部类实现。
让我们编写一个简单的迭代器模式测试程序,使用我们的集合和迭代器来遍历通道集合。
package com.journaldev.design.iterator; public class IteratorPatternTest { public static void main(String[] args) { ChannelCollection channels = populateChannels(); ChannelIterator baseIterator = channels.iterator(ChannelTypeEnum.ALL); while (baseIterator.hasNext()) { Channel c = baseIterator.next(); System.out.println(c.toString()); } System.out.println("******"); // Channel Type Iterator ChannelIterator englishIterator = channels.iterator(ChannelTypeEnum.ENGLISH); while (englishIterator.hasNext()) { Channel c = englishIterator.next(); System.out.println(c.toString()); } } private static ChannelCollection populateChannels() { ChannelCollection channels = new ChannelCollectionImpl(); channels.addChannel(new Channel(98.5, ChannelTypeEnum.ENGLISH)); channels.addChannel(new Channel(99.5, ChannelTypeEnum.HINDI)); channels.addChannel(new Channel(100.5, ChannelTypeEnum.FRENCH)); channels.addChannel(new Channel(101.5, ChannelTypeEnum.ENGLISH)); channels.addChannel(new Channel(102.5, ChannelTypeEnum.HINDI)); channels.addChannel(new Channel(103.5, ChannelTypeEnum.FRENCH)); channels.addChannel(new Channel(104.5, ChannelTypeEnum.ENGLISH)); channels.addChannel(new Channel(105.5, ChannelTypeEnum.HINDI)); channels.addChannel(new Channel(106.5, ChannelTypeEnum.FRENCH)); return channels; } }
运行程序:
Frequency=98.5, Type=ENGLISH Frequency=99.5, Type=HINDI Frequency=100.5, Type=FRENCH Frequency=101.5, Type=ENGLISH Frequency=102.5, Type=HINDI Frequency=103.5, Type=FRENCH Frequency=104.5, Type=ENGLISH Frequency=105.5, Type=HINDI Frequency=106.5, Type=FRENCH ****** Frequency=98.5, Type=ENGLISH Frequency=101.5, Type=ENGLISH Frequency=104.5, Type=ENGLISH
原文:https://www.cnblogs.com/swpudengyuheng/p/12832940.html