关键在于让每个类只与“直接朋友”交互:自身、参数对象、私有成员、new创建的对象;避免链式调用,改用语义化委托;返回值需克制,优先不可变副本或受限接口;多对象协作应由协调者统一调度。

关键在于让每个类只跟“自己真正了解”的对象打交道,不越级访问、不暴露内部、不硬编码导航路径。不是减少通信,而是把通信控制在可管理的范围内。
明确谁是你的“直接朋友”
一个类合法调用方法的对象,仅限以下四类:
- 自己(this)——调用自己的字段或方法
- 方法参数传入的对象——比如 process(Order order) 中的 order
- 私有成员变量持有的对象——如 private final Customer customer;
- 方法体内用 new 创建的对象——如 new PaymentValidator()
像 user.getProfile().getAddress().getCity() 就越界了:user 和 city 没有直接关系,中间隔了 profile 和 address。这种写法等于把三层结构全摊开,一改全崩。
用语义化委托替代链式调用
需要跨层获取信息时,别自己一层层点,让“近端对象”提供带业务含义的方法:
在 Java 中初始化和管理阿里云 SDK客户端。包括单例模式、线程安全、endpoint 与 region 配置、VPC 终端节点、同步与异步等。
立即学习“Java免费学习笔记(深入)”;
- ❌ 错误:order.getCustomer().getProfile().getPreferredLanguage()
- ✅ 推荐:order.getCustomerPreferredLanguage()(由 Order 封装)
- ✅ 更优:order.getCustomer().getPreferredLanguage()(把“偏好语言”归属 Customer,Order 不依赖 Profile)
重点不是删掉点号,而是让方法名表达“做什么”,而不是“怎么走”。比如 user.getCityName() 比 user.getAddress().getCity().getName() 更稳定、更易懂、更难出错。
返回值要克制,避免交出内部控制权
返回可变对象或原始引用,等于主动打开后门,让外部破坏封装:
- ❌ 危险:public List
- getItems() { return items; }
—— 外部可随意 add/remove - ✅ 安全:public List
- getItems() { return Collections.unmodifiableList(items); }
- ✅ 更好:public int getItemCount()、public Item getItem(String id) —— 只给能力,不给容器
- 同理,别直接返回 Date、StringBuilder 或数组,优先返回副本或不可变包装
多对象协作交给协调者统一调度
当几个对象天然要配合完成一件事(比如下单:查库存 → 扣减 → 创建订单 → 发通知),别让 Controller 层一手包办:
- ❌ 调用方直接串联:inventory.check() → inventory.deduct() → order.create() → notifier.send()
- ✅ 引入协调者:OrderService.placeOrder(orderRequest),内部封装流程和异常处理
- 这样调用方只需关注“我要下单”,不用知道库存怎么查、通知怎么发,也不用为每个环节的变更买单

















