私有计算逻辑需通过private方法封装+protected模板扩展+package-private协作+防御性拷贝实现“可复用、不可绕过、不可误改”。

应用变量访问控制符定义类内部私有计算逻辑的边界,核心是让计算过程“可复用、不可绕过、不可误改”。不是简单加个 private 就完事,而是通过权限组合 + 方法封装 + 数据保护,把计算逻辑真正关进可控的笼子里。
用 private 封住入口,但别让它成“死胡同”
字段声明为 private 是起点,但私有字段本身不执行计算。真正承载私有逻辑的是私有方法:
- 把校验、转换、聚合等中间计算步骤写成 private void validateAmount() 或 private BigDecimal computeTaxRate()
- 这些方法只在本类内被 public/setter/构造器调用,外部既看不到、也调不到
- 避免在 private 方法里暴露原始数据引用(比如返回 new ArrayList(items) 而不是 items)
用 protected 留出子类可扩展的计算钩子
如果未来可能需要定制计算行为(如不同地区税率规则),不要把全部逻辑锁死在 private 里:
- 把可变部分抽成 protected 模板方法,例如 protected double getBaseRate() { return 0.08; }
- 主计算流程(如 public final BigDecimal calculateTotal())调用它,保证结构稳定
- 子类可重写 getBaseRate(),但不能跳过校验或绕过总流程
用 package-private(default)协调同包内协作计算
当多个类共同完成一个业务计算链(如订单 → 折扣 → 发票),不必全公开,也不必全私有:
- 把共享的中间状态或辅助计算逻辑设为 default,例如 BigDecimal roundForInvoice(BigDecimal raw)
- 仅限 com.example.order 包内 Order、DiscountEngine、InvoiceGenerator 相互调用
- 对外部包完全隐藏,又避免重复实现或过度耦合
防御性拷贝 + 不可变返回,守住计算结果的边界
即使计算逻辑本身私有,若返回值可被外部修改,等于前功尽弃:
- getter 不直接返回 private List
- items
,而返回 Collections.unmodifiableList(items) - 若必须返回可变对象(如 Date),则返回新副本:return new Date(computedTime.getTime())
- 对入参也做防护:setter 中不直接赋值 this.dates = dates,而是 this.dates = new ArrayList(dates)

















