【问题标题】:Create subclass using parent's generic Builder使用父类的通用 Builder 创建子类
【发布时间】:2016-04-19 23:33:34
【问题描述】:

我正在探索使用 Builder 设计模式来创建父对象的子类,特别是基于子类的泛型类型。这句话有点令人困惑,我的意思是:

public class Animal(){
    private String name;
    private String gender;

    public Animal(Builder<?> builder){
        this.name = builder.name;
        this.gender = builder.gender;
    }

    public static Builder<T extends Animal>{
        private String name;
        private String gender;

        public Builder<T> setName(String name){
            this.name = name;
            return this;
        } 

        public Builder<T> setGender(String gender){
            this.gender = gender;
            return this;
        }        

        public T build(Class<T> clazz){
            try {
                Constructor<T> c = clazz.getDeclaredConstructor(Builder.class);
                c.setAccessible(true);
                return c.newInstance(this);
            }catch (Exception e){
                e.printStackTrace();
            }

            return null;
        }
    }
}

除了,这最终很容易出错和“hackish”。我希望能够拥有一个创建所有子类的 Builder。

问题

有没有更好的方法来做到这一点?也许 Builder 设计模式不适合我的需要。这有效,但感觉不对。

注意:这个问题的真正需求并不像 Animal 类的例子那么微不足道。您可以想象我正在尝试为包含许多参数的父类构建一个子类。使用构建器模式将使这更容易实例化,并且更容易为未来的子类扩展。

子类对象只有自己的方法。没有额外的字段,只有严格定义为其子类类型的方法。

即鸭子是鸟的一个子类,它会叫。鸸鹋是鸟的一个子类,但我不想让它嘎嘎叫,它只会跑。但我都希望他们有名字和性别。

【问题讨论】:

  • 有人评论了我为什么在此处发布此内容,而不是在代码审查中。原因是因为这是一个真正的 StackOverflow 问题......我确实提供了我尝试过的代码,但知道这不是一个干净的 Java 解决方案。我希望有人以我的示例代码为起点帮助我获得更好的答案,并以此为基础向我展示。

标签: java generics inheritance builder


【解决方案1】:

与其让用户指定 Animal 类,不如让每个 Animal 子类都有自己的 Builder 可以构建该 Animal。

即:

public abstract class Animal {
  protected Animal(Builder<?> builder) { ... }

  public abstract static class Builder<T extends Animal> {
    // setters for fields common to all animals go here

    public abstract T build();
  }
}

public final class Dog extends Animal {
  private Dog(Builder builder) {
    super(builder);
  }

  public static final class Builder extends Animal.Builder<Dog> {
    @Override
    public Dog build() {
      return new Dog(this);
    }
  }
}

【讨论】:

  • 这是我在阅读您的答案之前刚刚尝试过的。到目前为止我最喜欢它
猜你喜欢
  • 2021-11-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-09-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-05-07
相关资源
最近更新 更多