案例:打印多个项目报表,报表信息包括:项目名称、人数、开销等
类图:
代码:
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