改善既有代码的设计之重构技巧!
发表于更新于
代码设计代码设计改善既有代码的设计之重构技巧!
月伴飞鱼提炼函数(Extract Function)
提炼函数(Extract Function)是一种重构技术
- 它的目的是将一个大的函数拆分成若干个小的、功能单一的函数。
这样做可以提高代码的可读性、可维护性,并且可以复用那些小的函数。
假设我们有一个函数,它的任务是为一个在线商店的用户创建一个账户,并发送一封欢迎邮件。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| public class AccountService { public void createAccount(String email, String username, String pwd) { if (email == null || email.isEmpty()) { throw new IllegalArgumentException("Email cannot be empty."); } if (username == null || username.isEmpty()) { throw new IllegalArgumentException("Username cannot be empty."); } if (pwd == null || pwd.isEmpty()) { throw new IllegalArgumentException("pwd cannot be empty."); }
String welcomeMessage="Dear " + username + ", welcome to our service!"; } }
|
在这段代码中,createAccount
方法同时负责验证输入、创建账户和发送邮件。
我们可以通过提炼函数来拆分这个方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| public class AccountService { public void createAccount(String email, String username, String pwd) { validateAccountDetails(email, username, pwd); insertAccountIntoDatabase(email, username, pwd); sendWelcomeEmail(username); }
private void validateAccountDetails(String email, String username, String pwd) { if (email == null || email.isEmpty()) { throw new IllegalArgumentException("Email cannot be empty."); } if (username == null || username.isEmpty()) { throw new IllegalArgumentException("Username cannot be empty."); } if (pwd == null || pwd.isEmpty()) { throw new IllegalArgumentException("pwd cannot be empty."); } }
private void insertAccountIntoDatabase(String email, String username, String password) { }
private void sendWelcomeEmail(String username) { String welcomeMessage="Dear " + username + ", welcome to our service!"; } }
|
内联函数(Inline Function)
内联函数(Inline Function
)是一种重构技术
- 用于将一个函数的内容移动到该函数被调用的地方,然后移除原函数。
这种技术通常用于当一个函数的体积非常小,而且只被使用一次或者函数的内容几乎和它的名字一样清晰时。
我们通过一个例子来说明内联函数的重构过程。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| public class LogisticsService { public double processOrder(Order order) { doubleshippingCost= calculateShippingCost(order); return shippingCost; }
private double calculateShippingCost(Order order) { return getBaseShippingCost(order); }
private double getBaseShippingCost(Order order) { doublebaseCost=0.0;
return baseCost; } }
|
重构后的代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14
| public class LogisticsService { public double processOrder(Order order) { double shippingCost= getBaseShippingCost(order); return shippingCost; }
private double getBaseShippingCost(Order order) { double baseCost=0.0;
return baseCost; } }
|
提炼变量(Extract Variable)
将表达式的结果赋给一个临时变量,以提高表达式的清晰度。
1 2 3
| if (order.getTotalPrice() - order.getDiscounts() > 100) { }
|
重构后:
1 2 3 4
| doublenetPrice= order.getTotalPrice() - order.getDiscounts(); if (netPrice > 100) { }
|
内联变量(Inline Variable)
如果一个临时变量只被赋值一次,然后被直接使用,可以将其替换为直接使用赋值表达式。
1 2
| doublebasePrice= order.basePrice(); return (basePrice > 1000);
|
重构后:
1
| return order.basePrice() > 1000;
|
分解条件表达式(Decompose Conditional)
将复杂的条件逻辑分解为更清晰的逻辑块,提高其可读性。
1 2 3 4 5
| public void applyFee(Account account) { if (account.getBalance() < 0 && account.isOverdraftEnabled()) { account.addFee(OVERDRAFT_FEE); } }
|
重构后:
1 2 3 4 5 6 7 8
| public void applyFee(Account account) { if (shouldApplyOverdraftFee(account)) { account.addFee(OVERDRAFT_FEE); } } private boolean shouldApplyOverdraftFee(Account account) { return account.getBalance() < 0 && account.isOverdraftEnabled(); }
|
合并条件表达式(Consolidate Conditional Expression)
将多个条件表达式合并为一个,简化逻辑判断。
1 2 3 4 5
| if (isSpecialDeal()) { total = price * 0.95; } else { total = price * 0.98; }
|
重构后:
1
| total = price * (isSpecialDeal() ? 0.95 : 0.98);
|
移除死代码(Remove Dead Code)
删除不再被使用的代码,减少维护负担。
重构切量验证完成后,确保老代码无用,可直接删除主赠老逻辑calcTransferTimeForGift
方法以及下面依赖的方法