基本原则
健壮性原则
“在你发送的内容中保持保守,在你接受的内容中保持自由"
SOLID 原则
- S Single Responsibility Principle (SRP) 一个类/函数应该只有一个职责
- O Open/Closed Principle (OCP) 对扩展开放,对修改关闭
- L Liskov Substitution Principle (LSP) 子类应能替换父类而不破坏逻辑
- I Interface Segregation Principle (ISP) 客户端不应依赖它不需要的接口
- D Dependency Inversion Principle (DIP) 依赖抽象,而不是具体实现
组合替代继承
在JDBC驱动中,常见的风格即用 组合替代继承
组合通过引入另外一个类的实例,利用其功能,可以灵活动态的更改其实现
提炼函数
// 重构前
public void printOwing(double amount) {
printBanner();
// 打印详情
System.out.println("name: " + name);
System.out.println("amount: " + amount);
}
// 重构后
public void printOwing(double amount) {
printBanner();
printDetails(amount);
}
private void printDetails(double amount) {
System.out.println("name: " + name);
System.out.println("amount: " + amount);
}最佳实践
- 测试优先
- 使用IDEA提示,消除重复代码
- 逐步提炼
- 命名优先(如果找不到合适的名称,则表明代码块职责并不明确)
适用场景
- 消除重复代码
- 提高可读性
- 简化复杂逻辑
- 为代码块赋予明确语义
不适用场景
- 过度分解导致碎片化
- 代码块与上下文强耦合
// 不推荐:需要传递过多参数
public void process() {
int a = 10;
String b = "data";
boolean c = true;
// 提炼后的函数需要传递a、b、c三个参数
processSubtask(a, b, c);
}
private void processSubtask(int a, String b, boolean c) {
// 逻辑依赖a、b、c
}
// 问题:参数过多,可能意味着原函数职责过重- 性能敏感场景
- 循环内频繁调用函数
- 过多的参数传递
- 破环原有逻辑的原子性
引入参数对象
// 重构前
public void createEvent(String title, LocalDateTime startTime,
LocalDateTime endTime, String location) {
// ...
}
// 重构后
class EventParams {
String title;
LocalDateTime startTime;
LocalDateTime endTime;
String location;
}
public void createEvent(EventParams params) {
// ...
}分解条件表达式
- 提高代码的可读性。
- 使每个逻辑块的意图更清晰。
- 便于测试和维护。
消除代码谜题
避免使用复杂的布尔逻辑或嵌套条件,这些会让代码像谜题一样难以理解其真实意图。 重构前:
java
public boolean isEligibleForBonus(int yearsOfService, double salesAmount, boolean hasGoodPerformance, boolean isManager) {
// 这是一个复杂的布尔逻辑,需要仔细分析
return (yearsOfService > 5 && salesAmount > 100000) || (hasGoodPerformance && isManager);
}重构后:
java
public boolean isEligibleForBonus(int yearsOfService, double salesAmount, boolean hasGoodPerformance, boolean
isManager) {
boolean meetsServiceAndSales = yearsOfService > 5 && salesAmount > 100000;
boolean isHighPerformingManager = hasGoodPerformance && isManager;
return meetsServiceAndSales || isHighPerformingManager;
}
// 进一步优化,使用方法提取来命名条件
public boolean isEligibleForBonusFurtherOptimized(int yearsOfService, double salesAmount, boolean hasGoodPerformance,
boolean isManager) {
return meetsServiceAndSales(yearsOfService, salesAmount) || isHighPerformingManager(hasGoodPerformance, isManager);
}
private boolean meetsServiceAndSales(int yearsOfService, double salesAmount) {
return yearsOfService > 5 && salesAmount > 100000;
}
private boolean isHighPerformingManager(boolean hasGoodPerformance, boolean isManager) {
return hasGoodPerformance && isManager;
}减少认知负荷
通过使用卫语句(Guard Clauses)和策略模式等,减少代码阅读者在理解执行路径时需要跟踪的“分支”数量。
- 使方法的正常执行路径扁平化。
- 提前处理异常或特殊情况,然后返回。
- 提高代码的扫描性。 重构前(深度嵌套):
java
public String processOrder(Order order) {
if (order != null) {
if (order.isValid()) {
if (order.getTotalAmount() > 0) {
// 核心业务逻辑
return "Order processed successfully for " + order.getTotalAmount();
} else {
return "Order total amount must be positive.";
}
} else {
return "Order is not valid.";
}
} else {
return "Order cannot be null.";
}
}重构后(使用卫语句):
java
public String processOrder(Order order) {
if (order == null) {
return "Order cannot be null."; // 卫语句
}
if (!order.isValid()) {
return "Order is not valid."; // 卫语句
}
if (order.getTotalAmount() <= 0) {
return "Order total amount must be positive."; // 卫语句
}
// 核心业务逻辑,现在更清晰地位于方法的主体
return "Order processed successfully for " + order.getTotalAmount();
}
// 策略模式示例(用于替代复杂的 if-else if-else 链)
// 假设根据订单类型有不同的处理方式
interface OrderProcessor {
String process(Order order);
}
class StandardOrderProcessor implements OrderProcessor {
@Override
public String process(Order order) {
return "Standard order processed.";
}
}
class PriorityOrderProcessor implements OrderProcessor {
@Override
public String process(Order order) {
return "Priority order processed faster.";
}
}避免重复条件
相同的条件逻辑分散在代码的多个地方。
- 减少代码冗余。
- 确保逻辑修改时只需要在一个地方进行。
- 提高代码的可维护性。
重构前:
java
public void sendNotification(User user, String message) {
if (user != null && user.isActive() && user.hasEmail()) {
System.out.println("Sending email to " + user.getEmail() + ": " + message);
} else {
System.out.println("Could not send email to " + user.getName() + ": User not eligible.");
}
}
public void logUserActivity(User user, String activity) {
if (user != null && user.isActive() && user.hasEmail()) { // 重复的条件
System.out.println("Logging activity for " + user.getName() + ": " + activity);
} else {
System.out.println("Could not log activity for " + user.getName() + ": User not eligible.");
}
}重构后:
java
public void sendNotification(User user, String message) {
if (!isUserEligible(user)) {
System.out.println("Could not send email to " + user.getName() + ": User not eligible.");
return;
}
System.out.println("Sending email to " + user.getEmail() + ": " + message);
}
public void logUserActivity(User user, String activity) {
if (!isUserEligible(user)) { // 复用条件
System.out.println("Could not log activity for " + user.getName() + ": User not eligible.");
return;
}
System.out.println("Logging activity for " + user.getName() + ": " + activity);
}
private boolean isUserEligible(User user) {
return user != null && user.isActive() && user.hasEmail();
}
// 假设 Order 和 OrderType 是 OrderProcessor 策略模式的辅助类
class Order {
enum OrderType {STANDARD, PRIORITY}
private OrderType type;
private double totalAmount;
private boolean valid;
private String name;
private String email;
private boolean active;
// 构造函数、getter/setter等
public OrderType getType() {
return type;
}
public double getTotalAmount() {
return totalAmount;
}
public boolean isValid() {
return valid;
}
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public boolean isActive() {
return active;
}
public boolean hasEmail() {
return email != null && !email.isEmpty();
} // 假设hasEmail
}
class User {
private String name;
private String email;
private boolean active;
// 构造函数、getter/setter等
public String getName() {
return name;
}
public String getEmail() {
return email;
}
public boolean isActive() {
return active;
}
public boolean hasEmail() {
return email != null && !email.isEmpty();
} // 假设hasEmail
}