您的位置:首页 > 编程语言 > Java开发

java学习:处理逻辑的抽象,processor

2015-09-13 19:11 465 查看
以一个简单的例子来记这个抽象的技巧:

<问题>
实现三个方法:1、反转字符串;2、反转List;3、反转Set<String>里的所有元素
要求:进行参数校验、结果校验
</问题>

普通写法:(以下三个方法的逻辑都是1.参数校验2.处理3.结果校验,除了2以外基本都一样,多少代码因为各种校验而变得臃肿T_T)

public String reverse(String str){
if(str == null){
//打log,return
}
String s = StringUtils.reverse(str);
if(s == null){
//打log,return
}
return s;
}

public List reverse(List list){
if(list == null){
//打log,return
}
List result = Lists.reverse(list);
if(result == null){
//打log,return
}
return result;
}

public Set<String> reverse(Set<String> stringSet){
if(stringSet == null){
//打log,return
}
Set<String> set = Sets.newHashSet();
for(String s : stringSet){
set.add(StringUtils.reverse(s));
}
if(set == null){
//打log,return
}
return set;
}


抽象写法:(把传入参数和处理方法交给处理器,校验之类的事情处理器统一完成)

//首先定义接口,只有一个方法,传入一个参数,得到一个返回值
public interface Processor<P,R>{
public R process(P p);
}

//编写一个处理器,这个方法的逻辑是:1,参数校验2,进行处理3,结果校验

private <P, R> R doSomething(P p, Processor<P, R> processor){
if(p == null){
//打log,return
}
R result = processor.process(p);
if(result == null){
//打log,return
}
return result;
}

//下面三个问题要求的方法如下,把参数和处理的方式交个上面的doSomething处理,直接将结果返回就可以了

//可以看到三个方法都只是重写了process方法
public String reverse(String str){
return doSomething(str, new Processor<String, String>() {
@Override
public String process(String s) {
return StringUtils.reverse(s);
}
});
}

public List reverse(List list){
return doSomething(list, new Processor<List, List>() {
@Override
public List process(List list) {
return Lists.reverse(list);
}
});
}

public Set<String> reverse(Set<String> stringSet){
return doSomething(stringSet, new Processor<Set<String>, Set<String>>() {
@Override
public Set<String> process(Set<String> strings) {
Set<String> set = Sets.newHashSet();
for (String s : strings) {
set.add(StringUtils.reverse(s));
}
return set;
}
});
}


总结:
对于一些有很多公共操作的方法,可以考虑把它们不同的那一部分抽取出来,公共的部分在一个地方做,这样修改公共的某部分的时候不需要全部改一遍,逻辑也更清楚。

另附:
上面用到的List的reverse是guava提供的Lists.reverse()方法,这个方法的实现很有借鉴学习意义。一般说到反转List,想到的都是把List的元素 n 移到 size-n-1 的地方,时间复杂度为 n,但是guava的实现不一样,时间复杂度为1!它的做法是,重新实现一个reverseList类,继承List,重写List的方法,将正常的List中与位置相关的方法替换,如
get(index){
return forwardList.get(size - 1 - index);//forwardList是转换前的list,作为reserveList的成员变量存在
}

也就是说,数据一点都没有变,只是改变了外界操作数据的方式!
新的一种思路有木有,更详细的实现参看guava源码的具体实现~
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: