类中的Getter模式实现咨询:仅通过Getter访问类字段
嘿,我来帮你梳理下这个Getter模式的实现思路,你给出的代码其实已经踩中了核心点,但咱们可以把细节补全,让它更规范可靠~
实现Getter模式限制字段直接访问的正确姿势
核心原则非常清晰:把需要保护的字段设为私有(private),仅提供公共的Getter方法作为外部访问的唯一入口。这样既能完全控制字段的读取逻辑,还能实现懒加载、数据转换这类增强功能,就像你示例里针对customerName_的设计那样。
咱们一步步拆解并完善你的代码:
1. 字段的封装(核心步骤)
你已经做对了最关键的一步:
- 将
customerId设为private final:因为它是构造时传入的固定值,final保证后续不可修改,private彻底杜绝外部直接访问的可能 - 将
customerName_设为private:外部无法直接读取或修改,只能通过getCustomerName()方法间接获取
2. 完善Getter方法的逻辑
你的示例里的Getter已经有了懒加载的雏形,但还缺了返回值,咱们可以补充细节让它更健壮:
public class CustomerHelper { // 私有字段,外部无法直接访问 private final Integer customerId; private String customerName_ = null; // 构造方法初始化必填的customerId,增加参数校验避免无效输入 public CustomerHelper(Integer customerId) { if (customerId == null) { throw new IllegalArgumentException("customerId cannot be null"); } this.customerId = customerId; } // 公共Getter方法,是外部获取customerName的唯一入口 public String getCustomerName() { if (customerName_ == null) { // 懒加载逻辑:第一次调用才从数据库读取数据 customerName_ = customerDatabase.readCustomerNameFromId(customerId); // 额外后处理:比如统一格式、清理无效字符 if (customerName_ != null) { customerName_ = customerName_.trim().toUpperCase(); } } // 别忘了返回字段值! return customerName_; } // 如果业务需要,也可以给customerId添加Getter(因为它是final的,不会有修改风险) public Integer getCustomerId() { return customerId; } }
3. 额外注意事项
- 避免暴露引用类型字段:如果私有字段是List、Map这类引用类型,Getter不要直接返回原对象,要返回副本(比如
return new ArrayList<>(internalList)),防止外部代码修改内部状态 - 多线程场景的线程安全:如果这个类会在多线程环境下使用,
getCustomerName()需要加锁(比如synchronized)或者用volatile修饰customerName_,避免重复加载或出现半初始化的对象 - 命名规范统一:像
customerName_这种下划线结尾的私有字段命名,只要团队内部达成一致就没问题,也可以用小驼峰加前缀的方式(比如mCustomerName)
这样实现后,外部代码只能通过Getter方法访问类中的字段,完全无法直接操作私有成员,完美实现了你想要的Getter模式。
内容的提问来源于stack exchange,提问作者Coat
相关产品推荐
相关产品推荐

