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

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

参考资料

下文如有错漏之处,敬请指正

一、简介

定义

迭代器模式提供一种方法能访问容器对象中各个元素,而不暴露该对象的内部结构。

迭代器是为容器服务的,能容纳对象的所有类型都可以称之为容器,例如Collection集合类型、List类型、Set类型等,迭代器模式就是为解决遍历这些容器中的元素而诞生的。

特点

  • 迭代器模式是一种行为型模式

通用类图

在这里插入图片描述

迭代器模式的主要角色:

  • Aggregate

    抽象容器角色

    定义添加、删除元素以及创建迭代器对象的接口createIterator()。

  • ConcreteAggregate

    具体容器角色

    实现抽象容器接口定义的方法,返回一个具体迭代器的实例。

  • Iterator

    抽象迭代器角色

    定义访问和遍历容器元素的接口,通常包含 hasNext()是否已经访问到底部、first()获得第一个元素、next() 访问下一个元素方法。

  • Concretelterator

    具体迭代器角色

    实现抽象迭代器接口中所定义的方法,完成对容器对象元素的遍历。

优点

  • 访问一个容器对象的元素而无须暴露它的内部结构。

  • 支持以不同方式遍历同一个容器对象,甚至可以自定义迭代器的子类以支持新的遍历。

  • 增加新的容器类和迭代器类都很方便,符合开闭原则。

应用场景

  • 当需要为容器对象提供多种遍历方式时。
  • 当需要为遍历不同的容器对象提供一个统一的接口时。
  • 当访问一个容器对象的元素而无须暴露其内部细节时。

二、迭代器模式

需求:

一个公司有多个部门,每个部门有多个员工,现在部门用集合类型进行存储,部门员工用数组进行存储,使用迭代器模式访问聚合公司部门和部门员工的数据。

部门类:

package iterator;

public class Department {
    private String deptName;

    public Department(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String toString() {
        return "Department{" +
                "deptName='" + deptName + '\'' +
                '}';
    }
}

员工类:

package iterator;

public class Staff {
    private Department department;
    private String name;

    public void setDepartment(Department department) {
        this.department = department;
    }

    public Staff(String name) {
        this.name = name;
    }

    @Override
    public String toString() {
        return "Staff{" +
                "department=" + department +
                ", name='" + name + '\'' +
                '}';
    }
}

抽象容器角色:

package iterator;

public interface Aggregate {
    public void add(Object obj);
    public void remove(Object obj);
    public Iterator getIterator();
}

具体容器角色:

package iterator;

import java.util.ArrayList;
import java.util.List;

public class CompanyAggregate implements Aggregate {
    List<Object> departments=new ArrayList<>();
    @Override
    public void add(Object obj) {
        departments.add(obj);
    }

    @Override
    public void remove(Object obj) {
        departments.remove(obj);
    }

    @Override
    public Iterator getIterator() {
        return new CompanyIterator(departments);
    }
}
package iterator;


import java.util.LinkedList;
import java.util.Queue;

public class DepartmentAggregate implements Aggregate {
    private Object[] staffs=new Staff[100];
    private int index=-1;
    @Override
    public void add(Object obj) {
        staffs[++index]=obj;
    }

    @Override
    public void remove(Object obj) {
        int i=-1;
        for (Object staff : staffs) {
            ++i;
            if (staff.equals(obj)) {
                for(;i<index;++i){
                    staffs[i]=staffs[i+1];
                }
                --index;
                return;
            }
        }
    }

    @Override
    public Iterator getIterator() {
        return new DepartmentIterator(staffs,index);
    }

}

抽象迭代器:

package iterator;

public interface Iterator {
  	//	访问第一个元素
    Object first();
  	//	遍历到下一个元素
    Object next();
  	//	是否已经遍历到尾部
    boolean hasNext();
}

具体迭代器:

package iterator;

import java.util.List;

public class CompanyIterator implements Iterator {
    private List<Object> departments=null;
    private int index=-1;
    public CompanyIterator(List<Object> departments) {
        this.departments = departments;
    }

    @Override
    public Object first() {
        Object obj=departments.get(0);;
        return obj;
    }

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

    @Override
    public boolean hasNext() {
        if(index<departments.size()-1)
        {
            return true;
        }
        else
        {
            return false;
        }
    }
}
package iterator;

import java.util.List;

public class DepartmentIterator implements Iterator {
    private Object[] staffs=null;
    private int index=-1;
    private int size;

    public DepartmentIterator(Object[] staffs,int size) {
        this.staffs = staffs;
        this.size=size;
    }

    @Override
    public Object first() {
        Object obj=staffs[0];
        return obj;
    }

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

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

Client:

package iterator;

public class Client {
	public static void main(String[] args) {
		//  模拟公司添加部门
		Department d1 = new Department("技术部");
		Department d2 = new Department("营运部");
		Department d3 = new Department("公关部");
		Aggregate container = new CompanyAggregate();
		//  将部门加入到公司容器
		container.add(d1);
		container.add(d2);
		container.add(d3);
		//  获取公司部门的迭代器
		Iterator containerIterator = container.getIterator();
		//  打印所有部门的信息
		while (containerIterator.hasNext()) {
			System.out.println(containerIterator.next());
		}
		System.out.println("==========================");
		//  模拟部门添加员工
		Staff s1 = new Staff("张三");
		s1.setDepartment(d1);
		Staff s2 = new Staff("李四");
		s2.setDepartment(d2);
		Staff s3 = new Staff("王五");
		s3.setDepartment(d3);
		container = new DepartmentAggregate();
		//  将员工加入到部门容器
		container.add(s1);
		container.add(s2);
		container.add(s3);
		//  从部门容器中删除员工
		container.remove(s1);
		//  获取部门员工的迭代器
		containerIterator = container.getIterator();
		//  打印第一个员工
		System.out.println("打印第一个员工:" + containerIterator.first());
		System.out.println("==========================");
		//  打印所有员工
		while (containerIterator.hasNext()) {
			System.out.println(containerIterator.next());
		}

		/**
		 * 输出结果:
		 * Department{deptName='技术部'}
		 * Department{deptName='营运部'}
		 * Department{deptName='公关部'}
		 * ==========================
		 * 打印第一个员工:Staff{department=Department{deptName='营运部'}, name='李四'}
		 * ==========================
		 * Staff{department=Department{deptName='营运部'}, name='李四'}
		 * Staff{department=Department{deptName='公关部'}, name='王五'}
		 *
		 */

	}
}

当增加一个新的实体对象时(如合作企业),只需要增加对应的具体容器类和迭代器类,便可以通过对应的迭代器访问容器对象的内部数据。

三、总结

  • 迭代器模式是通过将容器对象的遍历行为分离出来,抽象成迭代器类来实现,其目的是在不暴露容器对象的内部结构的情况下,让外部代码透明地访问聚合的内部数据。
  • 迭代器模式目前已经是一个没落的模式,因为从JDK1.2版本开始增加java.util.Iterator这个接口,并逐步把Iterator应用到各个聚集类 (Collection)中,直接使用Collection下的实现类(Collection,List,Queue,Set等)就可以完美地解决问题。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值