类内的吸气剂模式?

Posted

技术标签:

【中文标题】类内的吸气剂模式?【英文标题】:Getter Pattern Within Class? 【发布时间】:2018-10-13 04:33:59 【问题描述】:

我在一个类中有一个只能直接从 getter 访问的字段。举个例子……

public class CustomerHelper 
  private final Integer customerId;
  private String customerName_ = null;

  public CustomerHelper(Integer customerId) 
    this.customerId = customerId;
  

  public String getCustomerName() 
    if(customerName_ == null)
      // Get data from database.
      customerName_ = customerDatabase.readCustomerNameFromId(customerId);
      // Maybe do some additional post-processing, like casting to all uppercase.
      customerName_ = customerName_.toUpperCase();
    
    return customerName_;
  

  public String getFormattedCustomerInfo() 
    return String.format("%s: %s", customerId, getCustomerName());
  

因此,即使在类本身内,像 getFormattedCustomerInfo 这样的函数也不应该能够通过 customerName_ 访问它。除了提供的 getter 函数之外,有没有办法强制类不直接访问字段?

【问题讨论】:

即使是私有类成员也可以在一个类中访问,所以我看不到这样做的直接方法。也许您可以将 getFormattedCustomerInfo 移动到单独的 util 类。为什么需要这个? 没有。一个类总是可以访问它的所有属性。唯一的可能是设置类抽象并编写一个具体类,由于属性设置为private,因此必须使用getter。两点说明: - 在 Java 中,在属性末尾写下划线是不常见的 - Formattable interface 是在类中添加所需功能的正确方法。 我不明白您为什么要这样做,但一种骇人听闻的方法是将字段提升到超类型并通过protectedpublic getter 公开它。除此之外,我认为这是不可能的。 【参考方案1】:

您似乎正在尝试缓存数据库值,并希望防止访问尚未缓存的值。

如果这是真的,那么变量customerName_ 不应该存在于CustomerHelper 类中;缓存的值应该更靠近数据库。

方法customerDatabase.readCustomerNameFromId(customerId)应该先查看一个缓存,如果缓存为空,调用数据库缓存结果。

实际上,customerName_ 成为缓存中的一个值:Map<Integer, String> cache,其中键为 customerId

【讨论】:

【参考方案2】:

Java 中没有这样的机制(或者至少我认为不应该有)。如果您确定应该禁止 getFormattedCustomerInfo 直接访问 customerName_,请创建另一个类并组合它们。

我会推荐CustomerInfoFormatter

另外,我会将customerName_ 更改为customerName,因为该语言通过显式声明支持隐私并且不需要添加更多指标。

【讨论】:

"另外,我会将 customerName_ 更改为 _customerName 以表明其隐私。" - 在 Java 中,您通常既不做一个也不做另一个。 我是一名 Python 开发人员,所以对我来说这看起来很正常,但你是对的,该语言通过显式声明来支持它。您可以提出修改建议。

以上是关于类内的吸气剂模式?的主要内容,如果未能解决你的问题,请参考以下文章

DDD - 在拥有映射器类时不暴露吸气剂

Vuex:为啥我们用大写字母编写突变、动作和吸气剂?

吸气剂'loadingStatus'在空颤时被调用

包含 Handler 的吸气剂

没有为“FirebaseUser”类定义吸气剂“实例”

如何使用带有可空值的吸气剂?