现在有个需求,老大让我把项目信息重新打印一份,分析总结一下所有项目存在的问题和解决办法。
很快我设计了一个类图:
类图非常简单,是个程序员都能实现,我们来看看简单的东西:
package com.nextvpu.myapplication;
/**
* Created by NEXTVPU on 2018/6/4.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//从老板这里看到的就是项目信息
public String getProjectInfo();
}
定义了一个接口,面向接口编程嘛,当然要定义接口了,然后看看实现类:
package com.nextvpu.myapplication;
import java.util.ArrayList;
/**
* Created by NEXTVPU on 2018/6/4.
* 所有项目的信息类
*/
public class Project implements IProject {
//定义一个项目列表,说有的项目都放在这里
private ArrayList<IProject> projectArrayList = new ArrayList<IProject>();
//项目名称
private String name = "";
//项目成员数量
private int num = 0;
//项目费用
private int cost = 0;
//定义一个构造函数,把所有老板需要看到的信息存储起来
public Project(String name,int num,int cost){
//赋值到类的成员变量中
this.name = name;
this.num = num;
this.cost = cost;
}
public Project(){}
@Override
public String getProjectInfo() {
String info = "";
//获得项目的名称
info = info+"项目名称是:"+this.name;
//获得项目的人数
info = info+"\t项目人数:"+this.num;
//项目费用
info = info+"\t项目费用:"+this.cost;
return info;
}
}
实现类比较简单,通过构造函数传递过来要显示的数据,然后放到getProjectInfo中显示,这个so easy!,然后我们老大要看看结果了:
private void Boss() {
//定义一个List,存放所有的项目对象
ArrayList<IProject> projects = new ArrayList<IProject>();
//增加星球大战项目
projects.add(new Project("星球大战项目", 10, 100000));
projects.add(new Project("星球项目", 5, 100));
projects.add(new Project("大战项目", 1, 10000));
for (int i = 4; i < 104; i++) {
projects.add(new Project("第" + i + "各项目", i * 5, i * 100));
}
for (IProject project :
projects) {
Log.e("xyz", " 把所有数据取出来=== " + project.getProjectInfo());
}
}
嗯,想了想,应该还有另外一种实现方式,因为遍历嘛,让我想到的就是迭代期模式,类图如下:
看着是不是复杂很多?是的,是有点复杂了,这个我等会说明原因,我们看代码实现,先IProject接口:
package com.nextvpu.myapplication;
/**
* Created by NEXTVPU on 2018/6/4.
* 定义一个接口,所有的项目都是一个接口
*/
public interface IProject {
//增加项目
public void add(String name,int num,int cost);
//从老板这里看到的就是项目信息
public String getProjectInfo();
//获得一个可以遍历的对象
public IProjectIterator iterator();
}
这里多了两个方法,一个是add方法,这个方法是增加项目,也就是说产生了一个对象后,直接使用add方法增加项目信息。我们再来看实现类:
package com.nextvpu.myapplication;
import java.util.ArrayList;
/**
* Created by NEXTVPU on 2018/6/4.
* 所有项目的信息类
*/
public class Project implements IProject {
//定义一个项目列表,说有的项目都放在这里
private ArrayList<IProject> projectArrayList = new ArrayList<IProject>();
//项目名称
private String name = "";
//项目成员数量
private int num = 0;
//项目费用
private int cost = 0;
//定义一个构造函数,把所有老板需要看到的信息存储起来
public 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.projectArrayList.add(new Project(name,num,cost));
}
public Project(){}
@Override
public String getProjectInfo() {
String info = "";
//获得项目的名称
info = info+"项目名称是:"+this.name;
//获得项目的人数
info = info+"\t项目人数:"+this.num;
//项目费用
info = info+"\t项目费用:"+this.cost;
return info;
}
@Override
public IProjectIterator iterator() {
return new ProjectIterator(this.projectArrayList);
}
}
项目信息类已经产生,我们再来看看我们的迭代期是如何实现的,先看接口:
package com.nextvpu.myapplication;
import java.util.Iterator;
/**
* Created by NEXTVPU on 2018/6/4.
* 定义一个接口
*/
public interface IProjectIterator extends Iterator{
}
如果我要实现一个容器或者其他API提供接口时,我一般都自己险些一个接口几成,然后在继承自己写的接口,保证自己的实现类只用实现自己写的接口(接口传递,当然也要实现顶层的接口),程序月度也清晰一些。我们继续看迭代器的实现类:
package com.nextvpu.myapplication;
import java.util.ArrayList;
/**
* Created by NEXTVPU on 2018/6/4.
* 定义一个迭代器
*/
public class ProjectIterator implements IProjectIterator {
//所有项目都放在这里ArrayList中
private ArrayList<IProject> projectArrayList = new ArrayList<IProject>();
private int currentItem = 0;
//构造函数传入projectList
public ProjectIterator(ArrayList<IProject> projectArrayList){
this.projectArrayList = projectArrayList;
}
//判断是否还有元素,必须实现
@Override
public boolean hasNext() {
//定义一个返回值
boolean b = true;
if (this.currentItem>=projectArrayList.size()||this.projectArrayList.get(this.currentItem)==null){
b = false;
}
return b;
}
//取得下一个值
@Override
public Object next() {
return (IProject)this.projectArrayList.get(this.currentItem++);
}
//删除一个对象
public void remove(){
//暂时没有使用到
}
}
最后我们来看BOSS方法的改动:
private void Boss() {
IProject projects = new Project();
// //增加星球大战项目
projects.add("星球大战项目", 10, 100000);
projects.add("星球项目", 5, 100);
projects.add("大战项目", 1, 10000);
for (int i = 4; i < 104; i++) {
projects.add("第" + i + "各项目", i * 5, i * 100);
}
//遍历一下ArrayList,把所有的数据都取出
IProjectIterator projectIterator = projects.iterator();
while (projectIterator.hasNext()){
IProject p = (IProject) projectIterator.next();
Log.e("xyz"," p.getProjectInfo === "+p.getProjectInfo());
}
上面的程序增加了复杂性,但是从面对对象的开发上来看,project.add()增加一个项目是不是更友好一些?
上面的例子就使用了迭代器模式,我们来看看迭代器的通用类图:
类图看起来很简单,但是你看用起来就很麻烦,就比如上面例子的两个实现方法,你觉得哪个简单?当然第一个了!其实Java已经把迭代器给我们准备了,我们再去写迭代器,有点多此一举了,所以现在很少有项目再独立写迭代器了,直接使用List或者Map就可以完成的解决问题.
迭代器模式DEMO下载地址:
迭代器模式demo