封装的核心是定义清晰边界和可控入口,java中通过构造器+不可变属性、聚合方法、只读视图、接口抽象来隐藏细节、暴露语义化api。

封装的核心不是“藏起来”,而是“定义清晰的边界和可控的入口”。在 Java 中,用封装简化复杂对象的外部调用,关键在于:把内部细节(如多层嵌套、状态校验、组合逻辑)收进类内部,对外只暴露少量语义明确、参数简洁的方法。
用构造器 + 不可变属性封装初始化逻辑
避免外部代码手动拼装对象、逐个 set 属性。把创建规则内聚到构造器中,强制校验和默认补全。
例如一个订单对象,包含用户、地址、商品列表、优惠券等:
- 不推荐:外部 new Order() 后反复调用 setXXX(),容易漏设或顺序错乱
- 推荐:提供带关键参数的构造器(如 userId, items),内部自动初始化 address = new DefaultAddress(), status = "CREATED"
- 进一步可加 Builder 模式,支持可选字段(如 couponCode),但主流程仍由 build() 方法统一组装和校验
用方法聚合多步操作,隐藏内部协作
当外部需要“完成一件事”却要调用多个对象、判断多个状态时,就把这个完整行为封装成一个方法。
比如“提交订单”实际涉及:校验库存 → 锁定库存 → 计算运费 → 生成订单号 → 持久化 → 发送通知。这些不该暴露给调用方。
- 对外只暴露 order.submit(),返回 SubmitResult(含 success / error msg)
- 内部由 Order 类协调 InventoryService、CalculationEngine、OrderRepository 等协作,调用方无需知道依赖谁、顺序如何
- 若某步失败(如库存不足),封装层统一处理回滚或返回结构化错误,不抛原始异常
用只读视图屏蔽敏感/易错状态
避免外部直接修改内部集合或状态字段,导致对象不一致。提供安全的访问方式。
- 不暴露 List
- items 字段,而提供 getItemsCopy() 返回不可修改副本(Collections.unmodifiableList)
- 状态变更不开放 setStatus(String),而是提供 confirm()、cancel() 等语义方法,内部控制状态流转(如 cancel 只在 CREATED 或 CONFIRMED 下生效)
- 对计算型字段(如 totalPrice)不存为字段,而是用 get 方法实时计算,确保始终与 items、coupon 保持一致
用接口隔离实现复杂度,面向契约编程
当对象本身职责较重(如支付网关),可定义精简接口,让调用方只依赖它,不感知具体实现是支付宝还是微信。
- 定义 PaymentProcessor 接口:process(PaymentRequest) → PaymentResult
- 外部只依赖该接口,传入 request 对象(已封装金额、用户、订单号等),不用管签名、回调地址、异步轮询等细节
- 具体实现类(AlipayProcessor、WxPayProcessor)各自封装协议差异,调用方完全无感
Java免费学习笔记:立即使用
解锁 Java 大师之旅:从入门到精通的终极指南











