如何优化存在重复逻辑的Java方法以消除代码冗余?
Java重复逻辑消除优化方案
核心思路是将通用的日志打印、耗时统计逻辑抽离为公共组件,仅将可变的业务执行逻辑、日志标识作为动态参数传入,常见实现方案如下:
1. 函数式接口封装(Java 8+ 首选,改动成本最低)
直接在当前接口内新增公共default方法,用函数式接口接收可变的业务逻辑,原方法直接调用公共方法传参即可:
公共抽离方法实现
default void runWithLogAndTime(String logTag, Runnable businessLogic) { LOGGER.info(logTag); final long start = System.currentTimeMillis(); businessLogic.run(); final long end = System.currentTimeMillis(); LOGGER.info(String.format("[%s] yep in %.2f sec", logTag, (end - start) / 1000f)); }
原方法改造后代码
default void method_one(int a, int b) { runWithLogAndTime("abc", () -> doMethod_A(a, b)); } default void method_two(int c) { runWithLogAndTime("xyz", () -> doMethod_B(c)); }
如果业务方法有返回值,可将Runnable替换为Supplier<T>,公共方法同步调整为返回业务逻辑的执行结果即可。
优势:无额外依赖、改动量极小,业务逻辑和通用切面逻辑完全解耦,可读性高。
2. 注解+AOP 实现(适合批量同类场景)
如果项目中存在大量需要做日志打印、耗时统计的方法,推荐用AOP切面实现零侵入改造:
- 自定义日志统计注解:
@Target(ElementType.METHOD) @Retention(RetentionPolicy.RUNTIME) public @interface LogExecutionTime { // 自定义日志标识 String logTag(); }
- 编写切面逻辑,拦截所有标注了上述注解的方法,在方法执行前后完成日志打印和耗时统计。
- 原业务方法改造后代码:
@LogExecutionTime(logTag = "abc") default void method_one(int a, int b) { doMethod_A(a, b); } @LogExecutionTime(logTag = "xyz") default void method_two(int c) { doMethod_B(c); }
优势:完全不侵入业务代码,所有统计逻辑统一管理,后续要调整日志格式、统计规则只需要修改切面代码即可。
3. 模板方法模式(适合抽象类分层架构)
如果你的逻辑是定义在抽象类而非接口中,可以用经典的模板方法模式实现:
抽象父类定义模板逻辑
public abstract class AbstractBusinessService { // 子类实现:返回当前业务的日志标识 protected abstract String getLogTag(); // 子类实现:具体业务逻辑 protected abstract void doBusiness(); // final修饰避免子类重写通用逻辑 public final void runWithLogAndTime() { String logTag = getLogTag(); LOGGER.info(logTag); final long start = System.currentTimeMillis(); doBusiness(); final long end = System.currentTimeMillis(); LOGGER.info(String.format("[%s] yep in %.2f sec", logTag, (end - start) / 1000f)); } }
业务子类实现
每个业务场景对应一个子类,实现两个抽象方法即可,通用逻辑完全复用父类。
优势:符合面向对象设计原则,扩展性强,适合业务分层明确的中大型项目。
方案选择建议:如果只有2~3个重复方法,优先选第一种函数式接口方案;如果同类场景超过5个,推荐用第二种AOP方案统一管理;如果本身就是基于抽象类做的业务架构,选第三种模板方法更贴合现有设计。
内容的提问来源于stack exchange,提问作者DerBenniAusA
相关产品推荐
相关产品推荐

