19.迭代器模式

1、院系结构

编写程序展示一个学校院系结构:

  • 需求是这样,要在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系。如图:

image-20221025230450462

2、传统方式问题

image-20221025230901500

  • 将学院看做是学校的子类,系是学院的子类,这样实际上是站在组织大小来进行分层次的

  • 实际上我们的要求是:

    • 在一个页面中展示出学校的院系组成,一个学校有多个学院,一个学院有多个系,
    • 因此这种方案,不能很好实现的遍历的操作
  • 解决方案 => 迭代器模式

3、基本介绍

  • 迭代器模式( lterator Pattern)是常用的设计模式,属于行为型模式

  • 如果我们的 集 合 元 素 是 用 不 同 的 方 式 实 现 \color{red}集合元素是用不同的方式实现 的,有数组,还有java的集合类,或者还有其他方式,

    • 当客户端要遍历这些集合元素的时候就要使用多种遍历方式,而且还会暴露元素的内部结构,
    • 可以考虑使用迭代器模式解决。
  • 迭代器模式,提供一种遍历集合元素的统一接口,

    • 一致的方法遍历集合元素,不需要知道集合对象的底层表示,
    • 即:不暴露其内部的结构。

4、原理类图

image-20221025233314012

5、案例解决

image-20221026013434555

组合+迭代器模式;

public class Client {
    public static void main(String[] args) {
        //创建大学
        OrganizationComponent<University> university = new University<>("u1", "u1");
        //创建学院
        university.add(new College<>("数统","数统"));

        Iterator<OrganizationComponent> iterator = university.createIterator();
        while (iterator.hasNext()) {
            OrganizationComponent next = iterator.next();
            Iterator<OrganizationComponent> iterator1 = next.createIterator();
            System.out.println("=========");
            System.out.println(next.name() + " " + next.des());
            System.out.println("=========");
            while (iterator1.hasNext()){
                OrganizationComponent next1 = iterator1.next();
                System.out.println(next1.name() + " " + next1.des());
            }
        }
    }

    /*
    =========
    c1 c1
    =========
    d1 d1
    d2 d2
    d3 d3
    d4 d4
    d5 d5
    =========
    c2 c2
    =========
    d1 d1
    d2 d2
    d3 d3
    d4 d4
    d5 d5
    =========
    数统 数统
    =========
    d1 d1
    d2 d2
    d3 d3
    d4 d4
    d5 d5
    */

}

public abstract class OrganizationComponent<E> {
    private String name;//名字
    private String des;//说明

    protected void add(OrganizationComponent<E> component) {
        //默认实现,叶子节点不需要重写add方法
        throw new UnsupportedOperationException();
    }

    protected void remove(OrganizationComponent<E> component) {
        //默认实现,叶子节点不需要重写remove方法
        throw new UnsupportedOperationException();
    }

    //==============================
    protected <T> Iterator<T> createIterator(){
        throw new UnsupportedOperationException();
    }
    
    public OrganizationComponent(String name, String des) {
        this.name = name;
        this.des = des;
    }
    
    public String name() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String des() {
        return des;
    }

    public void setDes(String des) {
        this.des = des;
    }
}

//University 就是 Composite,可以管理College
public class University<E> extends OrganizationComponent<E> {
    //存放的是College
    List<OrganizationComponent<E>> components = new ArrayList<>();

    public University(String name, String des) {
        super(name, des);
        //假设在这里创建了学院
        components.add(new College<>("c1","c1"));
        components.add(new College<>("c2","c2"));
    }

    // 重写add
    @Override
    protected void add(OrganizationComponent<E> component) {
        /// 将来实际业务中,University 的 add 和 College 的 add 不一定完全一样
        components.add(component);
    }

    //重写remove
    @Override
    protected void remove(OrganizationComponent<E> component) {
        components.remove(component);
    }

    //========================
    @Override
    protected Iterator<OrganizationComponent<E>> createIterator() {
        return new UniversityIterator<>(components);
    }


}
//校
public class UniversityIterator<E> implements Iterator<E> {
    List<E> departmentList;//大学是以List的方式存放院

    int index = -1;//索引

    public UniversityIterator(List<E> departmentList) {
        this.departmentList = departmentList;
    }

    //判断list中还有没有下一个元素
    @Override
    public boolean hasNext() {
        return index < departmentList.size() - 1;
    }

    @Override
    public E next() {
        index++;
        return departmentList.get(index);
    }
}


public class College<E> extends OrganizationComponent<E> {

    //存放的是"子"对象
    OrganizationComponent<E>[] components ;

    public College(String name, String des) {
        super(name, des);
        components = new Department[5];
        //假设在这里创建了系部
        add(new Department("d1","d1"));
        add(new Department("d2","d2"));
        add(new Department("d3","d3"));
        add(new Department("d4","d4"));
        add(new Department("d5","d5"));
    }

    int index = 0;

    // 重写add
    @Override
    protected void add(OrganizationComponent<E> component) {
        components[index] = component;
        index++;
    }

    //重写remove
    @Override
    protected void remove(OrganizationComponent<E> component) {
        //...
    }

    //==============================
    @Override
    protected Iterator<OrganizationComponent<E>> createIterator() {
        return new CollegeIterator<E>(components);
    }


}
//院系
public class CollegeIterator<E> implements Iterator<OrganizationComponent<E>> {
    OrganizationComponent<E>[] elementList;

    int position = -1;//索引

    public CollegeIterator(OrganizationComponent<E>[] departmentList) {
        this.elementList = departmentList;
    }

    //判断list中还有没有下一个元素
    @Override
    public boolean hasNext() {
        return position < elementList.length - 1;
    }

    @Override
    public OrganizationComponent<E> next() {
        position++;
        return elementList[position];
    }
}

6、迭代器模式-ArrayList源码

image-20221026130957702

  • 内部类 Itr:充当具体实现迭代器Iterator的类,作为ArrayList的内部类
  • List:充当了聚合接口,含有一个iterator() 方法,返回一个迭代器对象
  • ArrayList:是实现聚合接口List的子类,实现类iterator()
  • Iterator:接口系统提供
  • 迭代器模式解决了 不同集合(ArrayListLinkedList)统一遍历问题

7、迭代器模式的注意事项与细节

优点

  • 提供一个统一的方法遍历对象,客户不用再考虑聚合的类型,使用一种方法就可以遍历对象了。

  • 隐藏了聚合的内部结构,客户端要遍历聚合的时候只能取到迭代器,而不会知道聚合的具体组成。

  • 提供了一种设计思想,就是一个类应该只有一个引起变化的原因(叫做 单 一 责 任 原 则 \color{red}单一责任原则 )。

    • 在聚合类中,我们把迭代器分开,就是要把管理对象集合和遍历对象集合的责任分开,
    • 这样一来集合改变的话,只影响到聚合对象。而如果遍历方式改变的话,只影响到了迭代器。
  • 当要展示一组相似对象,或者遍历一组相同对象时使用,适合使用迭代器模式

缺点

  • 每个聚合对象都要一个迭代器,会生成多个迭代器不好管理类
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值