设计模式之迭代器模式

43 阅读1分钟

案例:打印多个项目报表,报表信息包括:项目名称、人数、开销等

类图:

代码:

public interface IProject {
    
    String getProjectInfo();

}

public class Project implements IProject {
    
    private String name; // 项目名称
    private int num; // 项目人数
    private int cost; // 项目支出
    
    public Project(String name, int num, int cost) {
        this.name = name;
        this.num = num;
        this.cost = cost;
    }
    
    
    @Override
    public String getProjectInfo() {
        StringBuilder builder = new StringBuilder();
        builder.append("项目名称:").append(name).append(",项目人数:").append(num).append(",项目支出:").append(cost);
        return builder.toString();
    }

}

public class Boss {

    public static void main(String[] args) {

        // 定义一个List,存放所有的项目对象
        ArrayList<IProject> projectList = new ArrayList<IProject>();

        projectList.add(new Project("财务系统改造", 10, 100000));
        projectList.add(new Project("OA系统升级", 100, 1000000));
        projectList.add(new Project("ERP系统开发", 10000, 10000000));
        // 增加100个其他项目
        for (int i = 4; i < 104; i++) {
            projectList.add(new Project("第" + i + "个项目", i * 5, i * 1000000));
        }

        // 遍历ArrayList,把所有项目的信息都取出
        for (IProject project : projectList) {
            System.out.println(project.getProjectInfo());
        }

    }

}

接下来使用迭代器模式实现同样的功能,类图:

代码:

public interface IProject {
    
    // 增加项目
    void add(String name, int num, int cost);
    
    // 获得项目信息
    String getProjectInfo();
    
    // 获得一个可以被遍历的对象
    IProjectIterator iterator();

}

public class Project implements IProject {
    
    private List<IProject> projectList = new ArrayList<>(); // 项目列表
    private String name; // 项目名称
    private int num; // 项目人数
    private int cost; // 项目支出
    
    public Project() {}
    
    private Project(String name, int num, int cost) {
        this.name = name;
        this.num = num;
        this.cost = cost;
    }
    
    @Override
    public void add(String name, int num, int cost) {
        this.projectList.add(new Project(name, num, cost));
    }
    
    @Override
    public String getProjectInfo() {
        StringBuilder builder = new StringBuilder();
        builder.append("项目名称:").append(name).append(",项目人数:").append(num).append(",项目支出:").append(cost);
        return builder.toString();
    }

    @Override
    public IProjectIterator iterator() {
        return new ProjectIterator(projectList);
    }

}

public interface IProjectIterator extends Iterator<IProject> {}

public class ProjectIterator implements IProjectIterator {
    
    // 项目列表
    private List<IProject> projectList = new ArrayList<>();
    private int currentItem = 0;
    
    public ProjectIterator(List<IProject> projectList) {
        this.projectList = projectList;
    }

    // 判断是否还有元素
    @Override
    public boolean hasNext() {
        return !(currentItem >= projectList.size() || projectList.get(currentItem) == null);
    }

    // 取下一个值
    @Override
    public IProject next() {
        return projectList.get(currentItem++);
    }

}

public class Boss {

    public static void main(String[] args) {

        IProject project = new Project();

        project.add(new Project("财务系统改造", 10, 100000));
        project.add(new Project("OA系统升级", 100, 1000000));
        project.add(new Project("ERP系统开发", 10000, 10000000));
        // 增加100个其他项目
        for (int i = 4; i < 104; i++) {
            project.add("第" + i + "个项目", i * 5, i * 1000000);
        }

        IProjectIterator iterator = project.iterator();
        while(iterator.hasNext()) {
            IProject p = iterator.next();
            System.out.println(p.getProjectInfo());
        }

    }

}

public class Boss {

    public static void main(String[] args) {

        IProject project = new Project();

        project.add(new Project("财务系统改造", 10, 100000));
        project.add(new Project("OA系统升级", 100, 1000000));
        project.add(new Project("ERP系统开发", 10000, 10000000));
        // 增加100个其他项目
        for (int i = 4; i < 104; i++) {
            project.add("第" + i + "个项目", i * 5, i * 1000000);
        }

        IProjectIterator iterator = project.iterator();
        while(iterator.hasNext()) {
            IProject p = iterator.next();
            System.out.println(p.getProjectInfo());
        }

    }

}

说明:

  • IProjectIterator这个接口中虽然没有定义任何方法,但它是有意义的。Java的核心思想之一就是面向接口编程,接口是对一类事物的描述,IProjectIterator这个接口说明了,其实现类一定是要创建一个包含一个或多个Project实例的迭代器。
  • 可以直接使用实现类实现Iterator接口,但为了保证代码结构清晰,一个好的习惯是,先定义一个接口继承JDK或者第三方的接口,再实现自定义的接口
  • 迭代器模式目前使用的已经不多了,因为大部分Java集合类都实现了Iterator接口,所以都提供了iterator()这个方法,所以基本不再需要单独写迭代器,使用JDK自带的集合即可解决问题。

本文原书《您的设计模式》作者:CBF4LIFE