目录
[1.2.1 添加新功能的时候对周边历史进行小型重构](#1.2.1 添加新功能的时候对周边历史进行小型重构)
[1.2.2 cide review 时](#1.2.2 cide review 时)
[1.2.3 有计划有目的的重构](#1.2.3 有计划有目的的重构)
[1.2.5 何时不该重构](#1.2.5 何时不该重构)
[1.3.1 保证重构前后行为一致。](#1.3.1 保证重构前后行为一致。)
[1.3.2 减少出现问题带来的影响](#1.3.2 减少出现问题带来的影响)
[1.4 常见的重构场景与方式](#1.4 常见的重构场景与方式)
[1.4.1 策略模式取代条件表达式](#1.4.1 策略模式取代条件表达式)
重构的目的、时机、难点
1.1重构的目的
① 优化代码结构、提高可读性
② 提高扩展效率
③降低修改代码的风险
1.2何时重构
第一次做某件事的时候只管去做,第二次做类似的事情的时候会反感,但无论如何还是可以去做,第三次再做类似的事情,你应该去重构,正如老话说的:事不过三,三则重构
1.2.1 添加新功能的时候对周边历史进行小型重构
① 当差不多代码赋值粘贴了3-5遍的时候
② 比如方法提炼、变量提炼、优化方法参数、消除重复逻辑等
③ 当然也要取舍,对于简单影响小的可以立即重构,如果比较复杂的有风险的可以先做几路,完成当前任务后或者另找时间重构。
1.2.2 cide review 时
让有经验的同学把知识传递给编写代码的同学,从而给予改进的灵感(老同学对业务更加熟悉,也更了解业务的变化点有助于作出合理的设计)
1.2.3 有计划有目的的重构
对于中小型重构通常在需求中见缝插针进行重构就可以了,但对于大型重构难度和影响相对要大一些,所以就要做好设计,确定影响范围,这通常需要安排整块时间。
1.2.4 出现线上问题
发生线上问题可以暴露出一些问题,这也是改进的好时机,比如上下游系统出现故障影响到你的系统,就可以思考耦合性太强了能不能解耦。
1.2.5 何时不该重构
① 重写比重构还容易(到这种程度重构的风险非常高)
② 隐藏在某个接口下运行稳定且极少修改的丑陋代码(难以看到收益)
1.3、重构的难点
1.3.1 保证重构前后行为一致。
① 使用IDEA 重构功能进行安全重构
② 单元测试
③功能测试
④回归测试后
1.3.2 减少出现问题带来的影响
① 灰度并且 开关
② 监控报警快速发现问题
1.4 常见的重构场景与方式
1.4.1 策略模式取代条件表达式
增加策略类,用于一些更复杂的场景。
public class AccessChecker {
public static String checkAccess(String role) {
if("admin".equals(role)) {
return "管理原可以访问所有功能";
} else if("user".equals(role)) {
return "普通用户只能访问部分功能";
} else if("guest".equals(role)) {
return "访客仅能浏览首页";
} else {
return "未知角色,请联系管理员";
}
}
}
使用策略模式 + 工厂模式优化
// 定义策略接口
public interface AccessStrategy {
String checkAccess();
}
// 实现策略类
public class AdminAccessStrategy implements AccessStrategy {
@Override
public String checkAccess() {
return "管理员可以访问所有功能"
}
}
public class UserAccessStrategy implements AccessStrategy {
@Override
public String checkAccess() {
return "普通用户只能访问部分功能";
}
}
// 创建工厂类
public class AccessStrategyFactory {
public static AccessStrategy getStrategy(String role) {
switch(role) {
case "admin":
return new AdminAccessStrategy();
case "user":
return new UserAccessStrategy();
default:
throw new IllegalArgumentException("Unknown role:" + role);
}
}
}
//应用策略
public class AccessManager {
public String getAccessLevel(String role) {
return AccessStrategyFactory.getStrategy(role).checkAccess();
}
}
或者
public enum UserRole {
ADMIN("admin", new AdminAccessStrategy()),
USER("user", new UserAccessStrategy()),
GUEST("guest", new GuestAccessStrategy());
private final String code;
private final AccessStrategy strategy;
UserRole(String code, AccessStrategy strategy) {
this.code =code;
this.strategy = strategy;
}
public String getCode() {
return code;
}
public AccessStrategy getStrategy() {
return strategy;
}
// 惊天方法,根据code 枚举对象
public static UserRole getByCode(String code) {
for(UserRole role : values()) {
if(role.getCode().equalsIgnoreCase(code)) {
return role;
}
}
throw new IllegalArgumentException("Unknown role code:" +code);
}
}
或者Spring 的依赖注入
@Autowired
private Map<String, AccessStrategy> strategies;
public AccessStrategy getStrategy(String roleCode) {
return strategies.get(roleCode.toLowerCase()+"strategy"));
}