【问题标题】:use Builder pattern from the constructor in a subclass在子类的构造函数中使用 Builder 模式
【发布时间】:2012-04-10 16:15:13
【问题描述】:

我目前正在使用 Builder 模式,密切关注 Wikipedia 文章 Builder 模式 http://en.wikipedia.org/wiki/Builder_pattern

中建议的 Java 实现

这是说明我的实现的示例代码

public class MyPrimitiveObject {
  private String identifier="unknown";
  public static class Builder {
    private final MyPrimitiveObject obj = new MyPrimitiveObject();
    public MyPrimitiveObject build() { return obj; }
    public Builder setidentifier (String val) {
     obj.identifier = val;
     return this;
    }
  }
  public static Builder createBuilder() { return new Builder(); }
  @Override public String toString() { return "ID: "+identifier; }
}

在我的一些使用这个类的应用程序中,我碰巧发现了非常相似的构建代码,所以我想在MySophisticatedObject 中继承MyPrimitiveObject 并将我所有重复的代码移到它的构造函数中......这就是问题所在.

如何调用超类 Builder 并将其返回的对象分配为我的实例?

public class MySophisticatedObject extends MyPrimitiveObject {
  private String description;
  public MySophisticatedObject (String someDescription) {
    // this should be the returned object from build() !!
    Builder().setidentifier(generateUUID()).build()
    description = someDescription;
  }     
}

【问题讨论】:

  • 这里是你如何做到这一点的详细版本:weblogs.java.net/node/642849 - 我通常使用静态工厂方法
  • @assylias,谢谢;我在发布之前已经找到了它,但这并不能回答我的问题。并不是我想为我的子类创建子类并发布一个新的 Builder,我只是想在我的构造函数中使用已经存在的超类构建器。有可能吗?
  • 我看错了你的问题。

标签: java builder


【解决方案1】:

您可能需要考虑使用嵌套的MySophisticatedObject.Builder,它扩展MyPrimitiveObject.Builder,并覆盖其build() 方法。在构建器中有一个受保护的构造函数来接受要设置值的实例:

public class MyPrimitiveObject {
  private String identifier="unknown";
  public static class Builder {
    private final MyPrimitiveObject obj;
    public MyPrimitiveObject build() { return obj; }
    public Builder setidentifier (String val) {
     obj.identifier = val;
     return this;
    }

    public Builder() {
        this(new MyPrimitiveObject());
    }

    public Builder(MyPrimitiveObject obj) {
        this.obj = obj;
    }
  }
  ...
}

public class MySophisticatedObject extends MyPrimitiveObject {
  private String description;

  public static class Builder extends MyPrimitiveObject.Builder {
    private final MySophisticatedObject obj;
    public Builder() {
      this(new MySophisticatedObject());
      super.setIdentifier(generateUUID());
    }     
    public Builder(MySophisticatedObject obj) {
      super(obj);
      this.obj = obj;
    }

    public MySophisticatedObject build() {
      return obj;
    }

    // Add code to set the description etc.
  }
}

【讨论】:

  • 谢谢,但是我需要在创建MySophisticatedObject 的实例时使用Builder,我想避免将创建代码移到构造函数中。
  • @PA.: 好吧,您当然必须更改 MyPrimitiveObject.Builder 代码以接受现有实例...此时您的 MySophisticatedObject 构造函数可以传入this - 但感觉有点乱。在同一类型层次结构中混合构建器和非构建器是很奇怪的。您可能要考虑使用我概述的构建器方法,但在 MySophisticedObject 中创建一个静态方法以轻松创建适当的实例。
  • 我明白了,让我考虑一下。我想将应用程序代码简化为 new 指令。
  • 我接受您的回答,因为它回应了我的原始帖子,但是,我发现了另一个问题。问题是对于我需要用于初始化超类的一些值,我需要先构造子类。想象在示例中 generateUUID() 需要一些“新生成器()”,它必须是子类对象的成员。如果您认为在评论中按原样发布问题,我最终可能会以新问题的形式发布。
  • @PA.: 你的意思不是很清楚,说实话......你可以在 builder 子类中做你喜欢的事情。
【解决方案2】:

你需要:

public class MySophisticatedObject extends MyPrimitiveObject {
  private String description;

  public static class SofisitcatedBuilder extends Builder {
    private final MySophisticatedObject obj = new MySophisticatedObject();
    public MyPrimitiveObject build() { return obj; }
    public Builder setDescription(String val) {
     obj.description = val;
     return this;
    }
  }

  public MySophisticatedObject (String someDescription) {
    // this should be the returned object from build() !!
    return new SofisitcatedBuilderBuilder()
         .setDescription(someDescription)
         .setidentifier(generateUUID()).build()
  }     
}

【讨论】:

    猜你喜欢
    • 2020-08-25
    • 2019-03-14
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-12-17
    • 2014-02-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多