重复代码提取为独立方法的核心是识别语义一致且变化点明确的重复逻辑,封装可变部分为参数,保持单一职责、无副作用、线程安全,并注重命名准确与位置合理。

重复代码提取为独立方法,核心是识别相同逻辑、封装可变部分、保持方法单一职责。不是所有重复都要拆,关键是“语义一致”且“变化点明确”。
识别可提取的重复片段
关注三类典型重复:
- 相同条件判断 + 相同处理逻辑(如 null 检查后取字段)
- 相同循环结构 + 相同元素处理(如遍历 List 做非空校验并转换)
- 相同异常处理模式(如捕获 IOException 后统一记录日志并返回默认值)
注意:仅字面相同但语义不同(比如两个地方都写了 i++)不算真正重复,不建议强行抽取。
设计方法签名:参数化差异点
把每次调用中“会变的部分”变成参数,常见方式有:
- 基础类型或对象参数(如
String prefix、User user) - 函数式接口参数(如
Function<string string> formatter</string>或Predicate<order> filter</order>),用于传入行为 - 必要时用 Builder 或配置对象封装多个相关参数(避免参数列表过长)
示例:原本两处都有 “若 name 不为空则转大写并加前缀”,可提取为:formatName(String name, String prefix, boolean toUpperCase)
保持方法内聚,不塞业务规则
独立方法应专注“做什么”,而非“为什么做”。例如:
- ✅ 好:
parseJson(String json, Class<t> type)</t>—— 只负责解析 - ❌ 差:
parseUserJsonAndValidate(String json)—— 混合了解析和校验,违反单一职责
校验逻辑应另抽为 validateUser(User user),再组合调用,方便单独测试和复用。
注意副作用与线程安全
提取后需检查方法是否意外修改了外部状态:
- 避免在方法内直接修改传入的集合或对象(除非明确设计为“就地更新”)
- 若方法内部缓存结果(如静态 Map),需考虑并发场景,加锁或改用
ConcurrentHashMap - 无状态工具方法(只读参数、纯计算)天然线程安全,优先采用
例如:将“遍历订单列表统计金额”提取为 sumOrderAmount(List<order> orders)</order>,应返回新值,而不是修改原 orders 中的某个字段。
不复杂但容易忽略的是命名和位置——方法名要准确表达意图(如 buildApiUrl 比 getUrl 更明确),且放在调用方能自然访问到的地方(同包工具类、服务类内部私有方法、或专门的 xxxHelper 类)。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











