简介
"用异常替换错误代码"是改进错误处理机制的重要重构手法。通过将程序错误以异常形式抛出,代替传统的错误代码返回方式,可以提升代码可读性和错误处理能力。
针对的症状(代码坏味道)
- 方法通过返回特殊值(如-1、null)表示错误状态
- 多层嵌套的错误代码检查
- 全局错误代码常量污染代码空间
用异常替换错误代码的详细步骤
- 定义异常类型
- 创建继承自Exception的自定义异常类
- 封装错误代码对应的错误信息
- 替换错误返回点
- 将return errorCode改为throw new Exception
- 移除方法返回值中的错误代码定义
- 调整调用方
- 添加try-catch块处理异常
- 移除原有的错误代码检查逻辑
- 清理残留代码
- 删除不再使用的错误代码常量
- 简化方法返回类型
示例
重构前代码:
class FileProcessor {
public static final int ERROR_FILE_NOT_FOUND = -1;
public static final int ERROR_READ_PERMISSION = -2;
int processFile(String path) {
File file = new File(path);
if (!file.exists()) {
return ERROR_FILE_NOT_FOUND;
}
if (!file.canRead()) {
return ERROR_READ_PERMISSION;
}
// 正常处理逻辑
return 0;
}
}
重构步骤:
-
定义文件处理异常:
class FileProcessException extends Exception { public FileProcessException(String message) { super(message); } } -
改造处理方法:
void processFile(String path) throws FileProcessException { File file = new File(path); if (!file.exists()) { throw new FileProcessException("File not found: " + path); } if (!file.canRead()) { throw new FileProcessException("Read permission denied: " + path); } // 正常处理逻辑 } -
调用方改造:
try { new FileProcessor().processFile("data.txt"); } catch (FileProcessException e) { System.err.println("Error: " + e.getMessage()); }
练习
基础练习题
-
简单错误代码替换
// 重构前 class Calculator { public static final int DIVIDE_BY_ZERO = -999; double divide(int a, int b) { if (b == 0) { return DIVIDE_BY_ZERO; } return a / (double) b; } }
进阶练习题
-
复合错误处理改造
// 重构前 class DatabaseConnector { public static final int ERROR_CONNECTION = 1001; public static final int ERROR_TIMEOUT = 1002; int connect(String url) { if (!validateUrl(url)) { return ERROR_CONNECTION; } if (checkTimeout(url)) { return ERROR_TIMEOUT; } // 连接逻辑 return 0; } }
综合拓展练习题
-
分层错误处理重构
// 重构前 class PaymentGateway { public static final int SUCCESS = 0; public static final int INVALID_CARD = 1; public static final int BALANCE_INSUFFICIENT = 2; int processPayment(Card card, double amount) { if (!card.isValid()) { return INVALID_CARD; } if (card.getBalance() < amount) { return BALANCE_INSUFFICIENT; } // 支付处理 return SUCCESS; } }
代码审查要点
-
优点:
- 明确分离正常流程和错误处理
- 支持异常传播机制
- 增强错误上下文信息携带能力
-
潜在问题:
- 避免过度使用受检异常
- 确保资源释放(使用try-with-resources)
- 保持异常继承体系的合理性