java学习:处理逻辑的抽象,processor
2015-09-13 19:11
465 查看
以一个简单的例子来记这个抽象的技巧:
<问题>
实现三个方法:1、反转字符串;2、反转List;3、反转Set<String>里的所有元素
要求:进行参数校验、结果校验
</问题>
普通写法:(以下三个方法的逻辑都是1.参数校验2.处理3.结果校验,除了2以外基本都一样,多少代码因为各种校验而变得臃肿T_T)
抽象写法:(把传入参数和处理方法交给处理器,校验之类的事情处理器统一完成)
总结:
对于一些有很多公共操作的方法,可以考虑把它们不同的那一部分抽取出来,公共的部分在一个地方做,这样修改公共的某部分的时候不需要全部改一遍,逻辑也更清楚。
另附:
上面用到的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源码的具体实现~
<问题>
实现三个方法: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源码的具体实现~
相关文章推荐
- java学习:Iterator数据加工厂
- Struts2学习笔记(十):Strut2表单标签详解
- 软考--J2SE
- java学习:用Map替代众多的if-else
- 我的java实验
- Java记录 -30- 包装类
- Java线程池使用说明
- java集合框架之java HashMap代码解析
- Java中HashMap实现原理初探
- Java学习笔记——cmd对java的编译以及cmd对cpp的编译
- java多线程
- Java并发编程:线程池的使用
- 解决在windows的eclipse上面运行WordCount程序出现的一系列问题详解
- java编程---万年历
- java String分类trim,substring,replaceAll,indexOf使用功能
- java中接口有什么作用?请创建一个接口(举例)
- java程序性能优化第三章
- java__泛型
- Spring MVC @ResponseBody 提示 406 The resource identified by this request……
- Java记录 -28- String Literals字面值