依赖倒置原则要求高层与低层模块均依赖抽象,抽象不依赖细节;java中通过接口/抽象类定义契约、构造注入依赖、返回抽象类型(如list而非arraylist)、封装异常实现;spring等ioc容器自动完成依赖注入。

依赖倒置原则(DIP)的核心是:高层模块不应依赖低层模块,二者都应依赖抽象;抽象不应依赖细节,细节应依赖抽象。在 Java 中,它不是靠语法强制,而是通过合理设计接口、抽象类和依赖注入来落地。
用接口或抽象类定义行为契约
避免让类直接依赖具体实现类,而是依赖一个抽象类型(如 interface 或 abstract class)。比如订单服务不该依赖 MySQLOrderRepository,而应依赖 OrderRepository 接口。
- 定义接口:interface OrderRepository { List
findAll(); void save(Order order); } - 具体实现:class JdbcOrderRepository implements OrderRepository { ... }
- 高层类依赖接口:class OrderService { private final OrderRepository repo; OrderService(OrderRepository repo) { this.repo = repo; } }
通过构造函数/方法参数注入依赖
让调用方决定传入哪个实现,而不是在类内部 new 具体对象。这使 OrderService 不感知数据库技术选型,也便于单元测试(可传入 Mock 实现)。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
- ✅ 正确:由外部创建并传入——new OrderService(new JdbcOrderRepository())
- ❌ 错误:类内硬编码——private OrderRepository repo = new JdbcOrderRepository();
- 也可用 setter 注入或工厂方法,但构造注入更清晰、不可变性更强
避免在抽象中引入具体类型
接口方法的参数、返回值、异常类型也应尽量保持抽象。例如不要让接口方法返回 ArrayList,而应返回 List;不要声明 throws SQLException,而应封装为自定义业务异常或 RuntimeException 子类。
- ✅ 好:List
findAll(); (返回接口) - ❌ 弱:ArrayList
findAll(); (绑定具体实现) - ✅ 好:void save(Order order) throws DataAccessException;(自定义抽象异常)
结合 Spring 等框架自动完成依赖管理
手动传参适合小项目;中大型项目常用 IoC 容器解耦。Spring 的 @Service、@Repository + @Autowired 就是 DIP 的典型应用——你只写接口和实现,容器负责把正确的 bean 注入到需要的地方。
- @Repository class JdbcOrderRepository implements OrderRepository { ... }
- @Service class OrderService { private final OrderRepository repo; public OrderService(OrderRepository repo) { this.repo = repo; } }
- Spring 启动时扫描并注入,业务代码完全不感知实例化过程
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










