java异常处理非常繁琐,过多的try-catch会使代码显得杂乱,而失去可读性。如下代码
Input input = null;
IOException processException = null;
try{
input = new FileInputStream(fileName);
//...process input stream...
} catch (IOException e) {
processException = e;
} finally {
if(input != null){
try {
input.close();
} catch(IOException e){
if(processException != null){
throw new MyException(processException, e,
"Error message..." +
fileName);
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName;
}
}
}
if(processException != null){
throw new MyException(processException,
"Error processing InputStream for file " +
fileName;
}
在上述代码中,我们catch住了所有的异常。这样的代码冗长可读性差,而且还极易忘掉一些异常。当处理一个流的时候,记得全部的异常处理是很难得。幸好,我们还有简单的设计模式去解决这个问题,下面的代码是一个模板去处理所有input stream的异常。
public abstract class InputStreamProcessingTemplate {
public void process(String fileName){
IOException processException = null;
InputStream input = null;
try{
input = new FileInputStream(fileName);
doProcess(input);
} catch (IOException e) {
processException = e;
} finally {
if(input != null){
try {
input.close();
} catch(IOException e){
if(processException != null){
throw new MyException(processException, e,
"Error message..." +
fileName);
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName;
}
}
}
if(processException != null){
throw new MyException(processException,
"Error processing InputStream for file " +
fileName;
}
}
//override this method in a subclass, to process the stream.
public abstract void doProcess(InputStream input) throws IOException;
}
在这个例子中,所有的流异常都被处理。我们只需继承这个类,并重写doprocess方法就可以了。比如:
new InputStreamProcessingTemplate(){
public void doProcess(InputStream input) throws IOException{
int inChar = input.read();
while(inChar !- -1){
//do something with the chars...
}
}
}.process("someFile.txt");
上面这个例子,我们创建一个 InputStreamProcessingTemplate的匿名子类实例,并调用其process方法。这是我们处理读写变得方便,我们只需关系我们的读写逻辑,而不必每次都去处理流异常。当然我们可以修改模板用于任何流处理,而不只是文件的读取。当然我们可以用接口代替抽象类实现模板。
public interface InputStreamProcessor {
public void process(InputStream input) throws IOException;
}
public class InputStreamProcessingTemplate {
public void process(String fileName, InputStreamProcessor processor){
IOException processException = null;
InputStream input = null;
try{
input = new FileInputStream(fileName);
processor.process(input);
} catch (IOException e) {
processException = e;
} finally {
if(input != null){
try {
input.close();
} catch(IOException e){
if(processException != null){
throw new MyException(processException, e,
"Error message..." +
fileName;
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName);
}
}
}
if(processException != null){
throw new MyException(processException,
"Error processing InputStream for file " +
fileName;
}
}
}
注意我们在 InputStreamProcessingTemplate 的process方法中增加一个参数InputStreamProcessor。这样我们可以这样使用:
new InputStreamProcessingTemplate()
.process("someFile.txt", new InputStreamProcessor(){
public void process(InputStream input) throws IOException{
int inChar = input.read();
while(inChar !- -1){
//do something with the chars...
}
}
});
这与抽象类相比,增加了代码的可读性。当然,我们还可以将process方法写为静态方法,这样我们调用的时候就不必每次都实例化了。
public class InputStreamProcessingTemplate {
public static void process(String fileName,
InputStreamProcessor processor){
IOException processException = null;
InputStream input = null;
try{
input = new FileInputStream(fileName);
processor.process(input);
} catch (IOException e) {
processException = e;
} finally {
if(input != null){
try {
input.close();
} catch(IOException e){
if(processException != null){
throw new MyException(processException, e,
"Error message..." +
fileName);
} else {
throw new MyException(e,
"Error closing InputStream for file " +
fileName;
}
}
}
if(processException != null){
throw new MyException(processException,
"Error processing InputStream for file " +
fileName;
}
}
}
调用方法如下:
InputStreamProcessingTemplate.process("someFile.txt",
new InputStreamProcessor(){
public void process(InputStream input) throws IOException{
int inChar = input.read();
while(inChar !- -1){
//do something with the chars...
}
}
});
总结
异常处理模板虽然简单,但是能很好的帮助我们格式化代码和减少错误发生。提高编码效率,模板方法一个让不可能 变可能的神奇模式。