封装本身不是解耦的直接手段,但通过隐藏实现、暴露稳定接口,为解耦提供基础;需协同接口抽象与依赖注入,如用orderrepository接口隔离dao实现、内部类封装高内聚逻辑、下沉重复校验,并通过di解除创建耦合。

封装本身不是解耦的直接手段,但它为解耦提供了基础结构——通过隐藏实现、暴露稳定接口,让类与类之间只依赖“契约”而非“细节”。重构紧耦合代码时,封装要和接口抽象、依赖管理协同使用,而不是单独靠 private + getter/setter 就完事。
用接口+封装分离行为与实现
紧耦合常表现为 Service 类直接 new 具体 DAO 或调用静态工具类。这时不能只把字段设为 private,而应把“谁来做”抽成接口,再让具体实现类封装自己的逻辑:
- 定义 OrderRepository 接口(在领域层),只声明 save()、findById() 等契约方法
- 让 JdbcOrderRepository 封装 JDBC 细节:私有字段(Connection、SQL 字符串)、私有方法(buildInsertSql()、mapToEntity())全部不对外暴露
- Service 类只依赖 OrderRepository 接口,不关心它是 JDBC 还是 Redis 实现
这样,替换数据库时只需新增一个 RedisOrderRepository,原有 Service 完全不用改——封装保障了实现的可替换性,接口保障了调用的稳定性。
把强依赖状态的逻辑移到内部类中封装
当一段逻辑必须频繁读写外部类的多个私有字段(比如订单编辑器要同时操作 status、items、updatedAt),又不想暴露这些字段给外界,成员内部类是最自然的封装载体:
- 声明 private class Editor,它能直接访问外部类所有 private 成员
- Editor 内部封装校验、状态转换、变更记录等完整流程,外部类只提供 public edit() 方法返回 Editor 实例
- 避免在外部类里堆砌 if-else 切换编辑状态,也避免把私有字段改成 package-private 让其他类“绕过封装”去访问
这种封装不是为了“藏起来”,而是把高内聚的协作逻辑收拢到一个有明确生命周期的单元里,天然降低与其他模块的耦合。
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
用封装消灭重复的校验与转换逻辑
紧耦合也常藏在“到处都写的校验”里:比如 5 个方法开头都有 if (user == null) throw …,或都手动 new SimpleDateFormat。这类重复说明职责没被正确封装:
- 提取为 private void validateUser(User user),放在当前类里——它只服务本类,不需 public,也不需 static
- 把日期格式化封装成 private static final DateTimeFormatter ORDER_TIME_FMT = …,或封装为静态工具方法(如 DateUtils.formatOrderTime())
- 关键点:封装后的方法要有明确输入输出,不操作 this 外部状态;若只修改 this 的几个字段,就留在当前类做非静态方法
重复逻辑下沉后,上层代码变薄,彼此不再因校验规则变动而连锁修改,耦合度自然下降。
配合依赖注入,让封装真正生效
光有封装不够——如果 OrderService 自己 new JdbcOrderRepository,那即使 Repository 内部封装得再好,耦合依然存在。必须切断创建链:
- 把 Repository 实现类交给 Spring 管理(@Repository),Service 用 @Autowired 注入接口
- 或者手工传参:构造函数接收 OrderRepository,不依赖具体类型
- 此时封装才起作用——你才能放心地替换实现、加代理、做 Mock 测试
没有依赖管理的封装,就像锁好了抽屉却把钥匙焊死在柜子上;加上依赖注入,抽屉才能真正独立开合。
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南










