1. 设计模式之迭代器模式:封装你的集合迭代逻辑

1.1. 介绍

迭代器模式提供一种方法顺序访问一个聚合对象中的各个元素,而又不暴露其内部的表示。

该方式可以提供一种统一的方法来遍历不同的聚合对象。需要遍历一个聚合对象,而又不希望暴露其内部结构时,可以使用该模式。

一般底层架构,中间件使用该模式比较多(eg:jdk 源码中集合类)。项目中如果有比较核心的业务,复杂对象,不想把集合对象结构暴露,可以使用该模式。

优点
1.支持多种遍历方式:不同的迭代器可以定义不同的遍历方式。
2.简化聚合类:聚合类不需要关心遍历逻辑。
3.多遍历支持:可以同时对同一个聚合对象进行多次遍历。
4.扩展性:增加新的聚合类和迭代器类都很方便,无需修改现有代码。

缺点
1.系统复杂性:每增加一个聚合类,就需要增加一个对应的迭代器类,增加了类的数量。

使用建议
1.当需要访问聚合对象内容而不暴露其内部表示时,使用迭代器模式。
2.当需要为聚合对象提供多种遍历方式时,考虑使用迭代器模式。

1.2. 实现及相关代码

假设一个案例,有一个名字集合类,里面包含名字的集合,想要遍历输出名字。

1.2.1. 没使用设计模式方式

案例代码

集合数据对象

public static class NameRepository {
    public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};
}

遍历方法

public static void main(String[] args) {
    NameRepository namesRepository = new NameRepository();
    String[] names = namesRepository.names;
    for(int i = 0 ; i < names.length ; i++){
        String name = names[i];
        System.out.println("Name : " + name);
    }
}

可能会遇到的问题

当业务调整,不得不调整集合数据对象内部结构,例如将 NameRepository 类中 String[] 换成 List<> 时,那么所有遍历的地方都要调整遍历方式,会引发大量地方调整代码,是很大的工作量。

集合类调整

public static class NameRepository {
    public List<String> names = new ArrayList<>();

    {
        names.add("Robert");
        names.add("John");
        names.add("Julie");
        names.add("Lora");
    }
}

遍历方式也要跟着调整

public static void main(String[] args) {
    NameRepository namesRepository = new NameRepository();
    List<String> names = namesRepository.names;
    for(int i = 0 ; i < names.size() ; i++){
        String name = names.get(i);
        System.out.println("Name : " + name);
    }
}

1.2.2. 使用设计模式方式

创建一个叙述导航方法的 Iterator 接口和一个返回迭代器的 Container 接口。实现了 Container 接口的实体类将负责实现 Iterator 接口。

IteratorPatternDemo,我们的演示类使用实体类 NamesRepository 来打印 NamesRepository 中存储为集合的 Names。 iterator_pattern_class

创建接口

public interface Iterator {
    public boolean hasNext();
    public Object next();
}

public interface Container {
    public Iterator getIterator();
}

创建实现接口的实体类

public static class NameRepository implements Container {
    public String[] names = {"Robert" , "John" ,"Julie" , "Lora"};

    @Override
    public Iterator getIterator() {
        return new NameIterator();
    }

    private class NameIterator implements Iterator {

        int index;

        @Override
        public boolean hasNext() {
            if(index < names.length){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names[index++];
            }
            return null;
        }
    }
}

迭代器设计模式方式输出打印

public static void main(String[] args) {
    NameRepository namesRepository = new NameRepository();

    for(Iterator iter = namesRepository.getIterator(); iter.hasNext();){
        String name = (String)iter.next();
        System.out.println("Name : " + name);
    }
}

当 NameRepository 实体类内部结构发生改变时

当集合实体类内部发生改变时,只需要自己调整内部迭代器接口,所有外部调用都不需要调整,大大的减少外部的耦合

public static class NameRepository implements Container {
    public List<String> names = new ArrayList<>();

    {
        names.add("Robert");
        names.add("John");
        names.add("Julie");
        names.add("Lora");
    }

    @Override
    public Iterator getIterator() {
        return new NameIterator();
    }

    private class NameIterator implements Iterator {

        int index;

        @Override
        public boolean hasNext() {
            if(index < names.size()){
                return true;
            }
            return false;
        }

        @Override
        public Object next() {
            if(this.hasNext()){
                return names.get(index++);
            }
            return null;
        }
    }
}

results matching ""

    No results matching ""