Java代码重构的实现方法
代码重构是改善既有代码设计而不改变其外部行为的过程,以下是具体的实现方法和案例:

重构的基本原则
- 小步修改:每次只做小的改动
- 测试保障:重构前必须有充分的测试
- 不改变功能:保持外部行为不变
常见重构案例及实现
提取方法(Extract Method)
重构前:
public void printOwing(String name) {
double outstanding = 0.0;
// 打印标题
System.out.println("*************************");
System.out.println("***** Customer Owes *****");
System.out.println("*************************");
// 计算欠款
Enumeration e = orders.elements();
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
outstanding += each.getAmount();
}
// 打印详细信息
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
重构后:
public void printOwing(String name) {
printBanner();
double outstanding = getOutstanding();
printDetails(name, outstanding);
}
private void printBanner() {
System.out.println("*************************");
System.out.println("***** Customer Owes *****");
System.out.println("*************************");
}
private double getOutstanding() {
double result = 0.0;
Enumeration e = orders.elements();
while (e.hasMoreElements()) {
Order each = (Order) e.nextElement();
result += each.getAmount();
}
return result;
}
private void printDetails(String name, double outstanding) {
System.out.println("name: " + name);
System.out.println("amount: " + outstanding);
}
提取类(Extract Class)
重构前:
public class Person {
private String name;
private String officeAreaCode;
private String officeNumber;
public String getTelephoneNumber() {
return "(" + officeAreaCode + ") " + officeNumber;
}
// getter/setter...
}
重构后:
public class Person {
private String name;
private TelephoneNumber officeTelephone = new TelephoneNumber();
public String getTelephoneNumber() {
return officeTelephone.getTelephoneNumber();
}
// getter/setter...
}
public class TelephoneNumber {
private String areaCode;
private String number;
public String getTelephoneNumber() {
return "(" + areaCode + ") " + number;
}
// getter/setter...
}
用多态替代条件表达式
重构前:
public double getSpeed() {
switch (_type) {
case EUROPEAN:
return getBaseSpeed();
case AFRICAN:
return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
case NORWEGIAN_BLUE:
return (_isNailed) ? 0 : getBaseSpeed(_voltage);
}
throw new RuntimeException("Should be unreachable");
}
重构后:
abstract class Bird {
abstract double getSpeed();
}
class EuropeanSwallow extends Bird {
double getSpeed() {
return getBaseSpeed();
}
}
class AfricanSwallow extends Bird {
double getSpeed() {
return getBaseSpeed() - getLoadFactor() * _numberOfCoconuts;
}
}
class NorwegianBlueParrot extends Bird {
double getSpeed() {
return (_isNailed) ? 0 : getBaseSpeed(_voltage);
}
}
引入参数对象(Introduce Parameter Object)
重构前:
public void addDateRange(Date start, Date end) {
// ...
}
public boolean isInRange(Date start, Date end, Date date) {
// ...
}
重构后:
public class DateRange {
private final Date start;
private final Date end;
public DateRange(Date start, Date end) {
this.start = start;
this.end = end;
}
public boolean contains(Date date) {
return !date.before(start) && !date.after(end);
}
}
public void addDateRange(DateRange range) {
// ...
}
public boolean isInRange(DateRange range, Date date) {
return range.contains(date);
}
重构工具的使用
IDE内置重构功能
- IntelliJ IDEA:Ctrl+Alt+Shift+T(重构菜单)
- Eclipse:Alt+Shift+T(重构菜单)
- NetBeans:Ctrl+Shift+R(重构)
常用重构快捷操作
// 重命名类/方法/变量 // Shift+F6 (IntelliJ) / Alt+Shift+R (Eclipse) // 提取方法 // Ctrl+Alt+M (IntelliJ) / Alt+Shift+M (Eclipse) // 内联变量 // Ctrl+Alt+N (IntelliJ) // 移动成员 // F6 (IntelliJ)
重构策略和步骤
重构流程
graph TD
A[识别坏味道] --> B[编写测试]
B --> C[小步重构]
C --> D[运行测试]
D --> E{测试通过?}
E -->|是| F[提交代码]
E -->|否| G[回退修改]
G --> C
F --> H[继续下一个重构?]
H -->|是| A
H -->|否| I[结束]
代码坏味道识别清单
- 过长方法(Long Method)
- 过大类(Large Class)
- 重复代码(Duplicated Code)
- 过长参数列表(Long Parameter List)
- 发散式变化(Divergent Change)
- 霰弹式修改(Shotgun Surgery)
- 依恋情结(Feature Envy)
实际项目重构案例
电商订单处理系统重构
重构前(存在重复代码和过长方法):
public class OrderService {
public void processOrder(Order order) {
// 验证订单
if (order.getItems().isEmpty()) {
throw new IllegalArgumentException("Order has no items");
}
if (order.getCustomer() == null) {
throw new IllegalArgumentException("No customer");
}
if (!order.getCustomer().isValid()) {
throw new IllegalArgumentException("Customer invalid");
}
// 计算总额
double total = 0;
for (Item item : order.getItems()) {
total += item.getPrice() * item.getQuantity();
// 应用折扣
if (item.getCategory() == Category.ELECTRONICS) {
total *= 0.9;
} else if (item.getCategory() == Category.BOOKS) {
total *= 0.95;
}
}
// 发送邮件
EmailService.sendOrderConfirmation(order.getCustomer().getEmail(),
order.getId(), total);
}
}
重构后:
public class OrderService {
private final OrderValidator validator;
private final PriceCalculator priceCalculator;
private final NotificationService notificationService;
public OrderService() {
this.validator = new OrderValidator();
this.priceCalculator = new PriceCalculator();
this.notificationService = new EmailNotificationService();
}
public void processOrder(Order order) {
validator.validate(order);
double total = priceCalculator.calculateTotal(order);
notificationService.sendOrderConfirmation(order, total);
}
}
public class OrderValidator {
public void validate(Order order) {
validateItems(order);
validateCustomer(order.getCustomer());
}
private void validateItems(Order order) {
if (order.getItems().isEmpty()) {
throw new IllegalArgumentException("Order has no items");
}
}
private void validateCustomer(Customer customer) {
if (customer == null) {
throw new IllegalArgumentException("No customer");
}
if (!customer.isValid()) {
throw new IllegalArgumentException("Customer invalid");
}
}
}
public class PriceCalculator {
public double calculateTotal(Order order) {
double total = 0;
for (Item item : order.getItems()) {
total += calculateItemPrice(item);
}
return total;
}
private double calculateItemPrice(Item item) {
double price = item.getPrice() * item.getQuantity();
return applyDiscount(price, item.getCategory());
}
private double applyDiscount(double price, Category category) {
DiscountStrategy strategy = DiscountStrategyFactory.getStrategy(category);
return strategy.applyDiscount(price);
}
}
重构最佳实践
- 测试驱动重构:先写测试,再重构
- 持续集成:频繁提交,避免大规模改动
- 代码审查:团队协作进行重构审查
- 文档更新:重构后更新相关文档
- 性能考虑:避免过度重构影响性能
通过以上方法,可以系统化地进行Java代码重构,提升代码质量和可维护性。
版权声明:NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
NBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
CBA直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
足球直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播
英超直播