• 设计模式之-迭代器(Iterator pattern)


    迭代器(iterrator)模式是一种行为设计模式,用于提供一种标准的方式来遍历一组对象,它被广泛的用在java Collection架构中提供一种标准接口用来遍历Collection元素。

    迭代器模式不仅用于容器(collection)遍历,根据我们需求也可以提供不同类型的迭代器。迭代器模式隐藏了容器具体的实现方式,只给客户端提供遍历方法。

    让我们用一种简单的例子来理解这种模式。假设我们有一个广播频道列表,用户想通过频道类型进行遍历,在这个例子中某些用户只对英文频道感兴趣,仅对它们进行处理,

    不想对其它类型频道进行处理。

    所以我们要提供一个频道容器给客户端,根据写入的逻辑来遍历频道并处理它们,但是客户的逻辑可能会有很多问题,我们不能确定客户端逻辑是否正确,如果客户数量的增长,那么它会变得非常难以维护。

    这里我们提供根据频道类型来使用迭代器模式。我们确保客户端只能通过迭代访问频道列表。


    第一部分我们制定我们的容器实现规则和iterrator接口:

    ChannelTypeEnum.java

    package com.journaldev.design.iterator;
     
    public enum ChannelTypeEnum {
     
        ENGLISH, HINDI, FRENCH, ALL;
    }

    ChannelTypeEnum定义了所有频道类型。

    Channel.java

    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;
        }
         
    }
    Channel用频率和频道类型属性


    ChannelCollection.java

    package com.journaldev.design.iterator;
     
     
    public interface ChannelCollection {
     
        public void addChannel(Channel c);
         
        public void removeChannel(Channel c);
         
        public ChannelIterator iterator(ChannelTypeEnum type);
         
    }

    ChannelCollection.java 制订了我们实现类规则,注意那些方法只提供了add,remove一个频道,但是没有提供返回整个频道列表方法,只有一个返回iterater对象用于遍历

    ChannelIterator定义如下方法:

    package com.journaldev.design.iterator;
     
    public interface ChannelIterator {
     
        public boolean hasNext();
         
        public Channel next();
    }

    现在基本接口与核心类已经准备好了,让我们实现iterater接口并处理迭代器

    ChannelCollectionImpl.java

    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;
            }
     
        }
    }

    注意我们使用内部类实现iterater接口,为了不被其它容器类使用。java collection实现也类似这样实现,使用内部类实现iterater接口

    我们使用一个简单测试程序使用我们的容器,根据频道类型对容器使用iterater对其进行遍历。

    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

    重点:
    1,当你想对外提供一种方式实现容器迭代,对于客户端隐藏内部实现逻辑
    2,迭代逻辑是包含在容器类内部实现,帮助客户端程序容易通过迭代器实现遍历










  • 相关阅读:
    加法原理和乘法原理
    布尔矩阵
    Codeforces Round #603 (Div. 2) A. Sweet Problem
    Codeforces Round #603 (Div. 2) D. Secret Passwords 并查集
    poj1611The Suspects并查集
    poj 2236 Wireless Network 并查集
    求斐波那契数的python语言实现---递归和迭代
    python语言实现阶乘的两种方法---递归和迭代
    栈实现二进制转十进制
    栈的基本操作
  • 原文地址:https://www.cnblogs.com/happyxiaoyu02/p/6818939.html
Copyright © 2020-2023  润新知