封装变量是什么
把裸字段变成访问器:先加读取与写入入口把访问收拢,再逐步收紧字段可见性,为后续的校验、惰性初始化与变更通知留出插入点。全局变量与跨模块共享状态尤其值得封装,因为它们是最难追踪的修改来源。
基本信息
| 步骤 | 封装读、封装写、收紧可见性、添加约束 |
|---|---|
| 典型场景 | 全局配置、单例状态、跨模块共享数据 |
| 收益 | 变更点集中,便于加校验与通知 |
| 常见搭配 | 值对象、不可变数据、依赖注入 |
| 判断信号 | 同一字段被多处直接读写 |
典型使用场景
- 全局配置对象被多处直接修改
- 单例里的可变状态没有统一入口
- 跨模块共享的缓存需要观察何时被清空
- 给字段加校验(非空、范围)之前先收拢写入口
- 需要惰性初始化时,用访问器承载初始化逻辑
封装前后
封装前后
// 之前:字段公开,任何地方都能改
public static Config config;
// 之后:入口收拢,写入时校验
private static Config config;
public static Config config() {
return config;
}
public static void setConfig(Config next) {
Objects.requireNonNull(next);
config = next;
}封装的四个阶段
| 阶段 | 动作 | 目的 |
|---|---|---|
| 封装读 | 改为通过访问器读取 | 先让读取路径可控 |
| 封装写 | 写入走统一入口 | 便于加校验与通知 |
| 收紧可见性 | 字段改为私有 | 阻止新的直接访问 |
| 添加约束 | 校验、不变式、变更通知 | 把规则写进入口 |
顺序有讲究:先建立访问入口,再切换调用方,最后隐藏字段。反过来做等于一次性打断所有调用点,迁移期无法编译。
只加写入方法不收敛约束,等于把裸字段换成方法名:校验与不变式仍没有地方落脚,问题只是从字段搬到了方法上。
对外暴露集合时返回只读视图或副本,避免调用方绕开访问器直接改内容;这类隐式修改最难排查,封装要把入口一起管住。