核心是控状态、明边界、保演化:用实例初始化块统一固化关键状态,按声明顺序构建依赖链;以接口定义职责边界,组合替代继承;封装可变性,依赖抽象而非实现。

复杂业务场景下设计 Java 对象,核心不是堆功能,而是控状态、明边界、保演化。重点在于让对象能稳住关键业务语义,同时不阻碍后续变化。
用构造块固化初始化顺序
避免在构造方法里写重复初始化逻辑,尤其当类有多个构造器时。把共性动作(如设置默认状态、生成时间戳、初始化集合)统一放进实例初始化块{}中。JVM 保证它在父类字段赋值后、所有构造方法体执行前运行,100%不遗漏。
- 订单对象始终要初始化 status = DRAFT、createTime = now()、items = new ArrayList<>(),这些全写在构造块里,比分散在三个构造方法中更可靠
- 配合字段声明顺序,可构建依赖链:先声明 private final Config config = loadConfig();,再在构造块中写 this.service = new OrderService(config);,编译器会强制校验顺序
按场景边界定义职责边界
一个对象不该“什么都能干”,而应对应一个清晰的业务场景切片。比如电商下单流程拆成“库存校验”“订单生成”“支付触发”三个独立对象,每个只管自己那块输入输出。
- 用接口定义契约,如 InventoryService.checkStock(productId, quantity),明确输入是商品ID和数量,输出是布尔结果+预留动作
- 不把校验、扣减、日志、告警全塞进一个方法;而是让 InventoryChecker、InventoryDeductor、InventoryLogger 各司其职,靠组合而非大类承载
优先组合,慎用继承
继承容易导致“子类被迫实现父类所有语义”,反而绑死扩展。多数业务对象关系更适合组合——用“有”代替“是”。
立即学习“Java免费学习笔记(深入)”;
- 订单对象不继承自“支付对象”,而是持有 PaymentProcessor 和 RefundPolicy 两个策略对象
- 用户对象不继承 VIPUser 或 Guest,而是通过 RoleStrategy 或 PermissionScope 组合动态赋予能力
- 需要多态时才考虑继承,且必须满足里氏替换原则:子类能完全替代父类被调用,不破坏原有逻辑
封装可变性,暴露稳定性
把可能随业务变化的部分(如计费规则、审批流、通知渠道)抽成接口或函数式参数,对象内部只依赖抽象,不绑定具体实现。
- 订单创建时传入 FeeCalculator 实例,而不是硬编码 if-else 判断会员等级
- 用 Supplier<LocalDateTime> 替代直接 new LocalDateTime.now(),便于测试时注入固定时间
- 配置项(如超时阈值、重试次数)从构造块或 Builder 中注入,不写死在字段初始化里


















