具有最终不变性的不可变对象的设计模式

时间:2016-11-19 20:06:49

标签: java design-patterns

我想构造一个对象,我想将其作为不可变对象传递给应用程序的其余部分。但是这里的问题是某些字段在对象构造时直接可用,而有些字段需要来自RPC调用的响应。 RPC调用需要一些时间才能返回,我不希望在此期间阻止调用者,因为我希望调用者使用在对象构造时间内传入的字段。我有一个设计,但想知道是否有标准模式。

以下示例说明了我要找的内容。

public class Player {
  private int name;  // Available at construction time
  private int age;   // Available at construction time

  private String profileUrl;  // Need to get this from an RPC call

  // useful for checking whether we have profileUrl 
  private boolean profileUrlAvailable = false; 

  Player(int name, int age) {
    this.name = name;
    this.age = age;
  }

  // usual getter methods

  // Package protected for immutability
  void setProfileUrl(String profileUrl) {
    this.profileUrl = profileUrl;
    this.profileUrlAvailable = true;
  }

  public boolean hasProfileUrl() {
    return profileUrlAvailable;
  }

  // throws if profile url is not yet available.
  public String getProfileUrl() {
    if (!profileUrlAvailable) {
       throw new IllegalStateException("Profile url not available");
    }
    return profileUrl;
  }
}

这个例子不是线程安全的,考虑一下它会被处理掉。为了能够让感兴趣的呼叫者知道配置文件URL何时可用,我将公开一种方法来注册callables,当profileUrl可用时,该方法将被通知。

我认为如果我添加几个类似于profileUrl的字段最终可用,这种方法效果不佳。我想找到解决方法的建议。

如果我确保所有与profileUrl类似的字段同时可用(即,使用单个方法设置它们),它是否会简化?

1 个答案:

答案 0 :(得分:0)

Lazy initialization是否符合您的需求?

代码段:

public class Player {
private int name;  // Available at construction time
private int age;   // Available at construction time

private String profileUrl = null;  // Need to get this from an RPC call 

Player(int name, int age) {
  this.name = name;
  this.age = age;
}

// usual getter methods

public String getProfileUrl() {
  if (profileUrl == null) {
     profileUrl = Remote.getProfileUrl();
  }
  return profileUrl;
 }
}

您可以将RPC移动到访问者方法,在本例中为getProfileUrl。 只有第一次调用才会实际阻止等待远程过程完成。

需要这种大量初始化的字段的其他访问器方法看起来是一样的。

如果您可以通过这种方式使用Player课程,并且能够为将来的通话缓存profileUrl,那么您可以解决问题并达到此模式的目标。