匿名类及其使用
匿名类
对很多情况而言,定义在方法内部的类名意义不大,它可以保持为匿名的,程序员关心的只是它的实例名.
如:
---------------------------------------------------------------------------------------------------------------------------
Runnable runner=new Runnable(){
public void run(){
// Run statememnt
}
}
---------------------------------------------------------------------------------------------------------------------------
理解匿名类
匿名类并不难理解,它只是把类的定义过程和实例的创建过程混合而已,上页的语句实际上相当于如下语句:
---------------------------------------------------------------------------------------------------------------------------
// 定义类
Public class Runner implements Runnable{
public void run(){
// do sth
}
}
// 创建实例
Runner runner=new Runner();
---------------------------------------------------------------------------------------------------------------------------
使用匿名类的筛选解耦过程
需求:从公司的职员列表中,找出男性且年龄大于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);
}
}
---------------------------------------------------------------------------------------------------------------------------
传统方法的缺陷
这种写法没有错,但是不是面向对象的写法,它有以下缺陷:
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);
这段代码成功的把查询条件作为一个接口分离了出去,接口代码如下:
public interface MemberFilter{
public boolean accept(Member member);
}
查询函数的变化
而类Company增加了这样一个函数:
public List searchMembers(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也同时拥有了数据和行为,而不是原来的数据容器了.