环绕执行模式(execute around):做资源处理时一个常见的操作模式就是打开一些资源,执行一些代码,然后将这些资源关闭。这些打开资源,关闭资源的操作总是十分的类似并且围绕着那些需要处理的重要代码,这就是环绕执行模式。
在《唯品会Java开发手册》当中,方法设计第四条:
【推荐】尽量减少重复的代码,抽取方法
超过5行以上重复的代码,都可以考虑抽取公用的方法。
就直接列举书中的例子了:
public static String processFile() throws IOException {
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
return br.readLine();
}
}
这个例子当中真正重要的独一无二的代码就是那一句return,而且这个例子实际上已经使用了java7中的try,已经做到了一些简化。但此时它的灵活性不够,只能读文件中的一行元素,若是想要读两行,三行,那就得不断的对函数进行复用。即重用设置和清理的代码,并且让函数执行不同的操作。即我们需要将它的行为参数化,将一种方法传递给processFile(),然后就可以使用lambda进行操作。
但如上篇当中介绍,Lambda仅仅可以使用于函数式接口,所以我们需要创建一个函数式接口。
***注意点:任何函数式接口都不允许抛出受检异常(checked exception)。如果你需要Lambda 表达式来抛出异常,有两种办法:定义一个自己的函数式接口,并声明受检异常,或者把Lambda 包在一个try/catch块中。
@FunctionalInterface
public interface BufferedReaderProcessor {
String process(BufferedReader b) throws IOException;
}
之后我们就可以将这个接口当作参数传入processFile()当中。
public static String processFile(BufferedReaderProcessor p) throws IOException{
try (BufferedReader br = new BufferedReader(new FileReader("data.txt"))) {
return p.process(br);
}
}
最后就可以使用Lambda灵活的处理了。
处理一行:
String oneLine = processFile((BufferedReader br) -> br.readLine());
处理两行:
String twoLines = processFile((BufferedReader br) -> br.readLine() + br.readLine());
总结:就是首先得记得行为参数化,然后得想办法写出接口,或者直接用java当中有的函数式接口,然后执行一个行为,lambda允许直接内联,为函数式接口方法提供实现,并将整个表达式作为函数式接口的一个实例。最后就可以执行Lambda方法。