需求:从公司的职员列表中,找出男性且年龄大于22的成员.
传统写法:
// 传统查询
List allmembers=company.getMembers();// 取得所有成员
List results=new ArrayList();// 结果列表
for(Iterator it=allmembers.iterator();it.hasNext();){
Member member=(Member)it.next();
if(member.getAge()>22 && member.isMale()){ // 筛选
results.add(member);
}
}
System.out.println(results); // 输出结果
输出:
[Name=关羽 Age=28 Male=true, Name=张飞 Age=27 Male=true]
这种写法没有错,但是不是面向对象的写法,它有以下缺陷:
1.查询条件和筛选过程没有分离.
2.这样写的后果使Company变成了一个失血模型而不是领域模型.
3.换查询条件的话,上面除了 筛选 一句有变化外其它都是模板代码,重复性很高.
真正符合OO的查询应该是这样:
// OO化查询
MemberFilter filter1=new MemberFilter(){
public boolean accept(Member member) {
return member.isMale() && member.getAge()>22;
}
};
List ls=company.listMembers(filter1);
System.out.println(ls);
输出:
[Name=关羽 Age=28 Male=true, Name=张飞 Age=27 Male=true]
这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:
public interface MemberFilter{
public boolean accept(Member member);
}
而类Company增加了这样一个函数:
public List listMembers(MemberFilter memberFilter){
List retval=new ArrayList();
for(Iterator it=members.iterator();it.hasNext();){
Member member=(Member)it.next();
if(memberFilter.accept(member)){
retval.add(member);
}
}
return retval;
}
这就把模板代码归结到了类内部,外面不会重复书写了.Company也同时拥有了数据和行为,而不是原来的数据容器了.
这才是OO化的查询.
全部代码请见:
http://www.blogjava.net/Files/junglesong/Filter.rar
