核心是依赖倒置与接口隔离:类只依赖定义清晰、职责单一的名词接口,依赖通过构造函数注入,实现类不创建依赖,由外部统一组装,提升可测性与解耦性。

核心是让类只依赖接口,不依赖具体实现;依赖对象由外部传入,而不是自己创建。
定义清晰、职责单一的接口
接口不是为了“有接口”而存在,而是为了解耦和明确契约。每个接口应聚焦一个角色或能力,比如 PaymentProcessor 负责支付执行,NotificationSender 负责消息通知,不混在一起。
- 用名词命名接口(如 OrderRepository),避免动词+er 组合(如 OrderSaver)
- 方法签名要稳定:参数尽量用不可变对象或基础类型,返回值优先用接口或值对象
- 合理使用默认方法封装通用逻辑,但别把业务主流程塞进去
实现类专注具体逻辑,不主动创建依赖
实现类只做一件事:把接口声明的行为落地。它不应 new 其他服务,也不应读配置、连数据库——这些都该通过构造函数或 setter 传进来。
- 构造函数注入是最推荐的方式,能保证依赖不为空、对象一创建就完整
- 避免在实现类里写
new DatabaseService()或SpringContext.getBean(...) - 如果某个实现需要可选行为(如日志开关),可通过布尔参数或策略接口传入,而非硬编码判断
依赖由外部统一组装,不散落在各处
谁来 new 对象、谁来把 A 和 B 连起来?这个职责不该由业务类承担。可以是:
在调试 Java 后端 API 故障时使用此技能,尤其适用于以下任务:分析日志、跨 Controller、Service 和 Mapper 层追踪请求、定位异常根因、检查 SQL 执行或参数流转,以及生成简洁的诊断结论与修复方案。
- 手动组装:测试类中直接 new 实现类并传入 mock 依赖
- 工厂类:按条件返回不同实现,比如
PaymentFactory.create(“alipay”) - 框架托管:Spring 的
@Service+@Autowired,或 Micronaut 的编译期注入
关键不是用没用框架,而是“创建”和“使用”彻底分离。
测试时天然友好,无需复杂 Mock
因为类只依赖接口,单元测试时可以直接传入轻量实现或手工 stub:
- 不用 PowerMock 去 mock 构造器或静态方法
- 对第三方 SDK 封装一层接口(如 SmsClient),测试时替换为内存版实现
- 集成测试时再换回真实客户端,边界清晰
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










