【问题标题】:Builder patterns and generic type that extends itself构建器模式和扩展自身的泛型类型
【发布时间】:2020-06-01 13:22:49
【问题描述】:

我正在尝试通过继承实现 Builder 模式,并找到了以下 solution

这是B类:

public class B extends A {
    public static abstract class Builder<T extends Builder<T>>
        extends A.Builder<T> {

        @Override
        public abstract T getThis();

        public Builder Bmethod() {
            //implementation
            return this;
        }

        public B build() {
            return new B(this);
        }
    }

    private B(Builder builder) {
        super(builder);
        //B field assignment
    }
}

现在我想让 C 类也可扩展。我就是这样做的:

public class C extends B {
    ...
    public static class Builder<T extends Builder<T>> extends B.Builder<T> {
        ....
    }
}

所以,在C 中,我们有可以扩展的构建器,例如D。我的问题是创建 C.Builder 实例的正确方法是什么。我的意思是,我应该在它的泛型中设置什么:

C.Builder<WHAT HERE> builder = new C.Builder<>();

【问题讨论】:

  • B 长什么样子?
  • 只是一个模糊的想法,但我会将C 设计为可扩展(因此具有与B 相同的抽象构建器)或不可扩展(因此具有创建C 实例的具体构建器)。混合具体类和继承虽然可能总是有问题并且可能令人讨厌。
  • 只是我在原始文章中看到的术语歧义。 Builder 是一个允许您构建复杂事物的类。喜欢: var builder = new SQLBuilder(); builder.addTable("员工"); builder.addJoin("工资", "id","id_employee"); builder.addWhere(SQLWhere.equals("id", 6));字符串查询 = builder.build();构建器模式不需要链接调用的能力,但可以使其更具表现力。
  • 使用静态导入它可能看起来像:select("Employees").innerJoin("Salaries", eq("id","id_employees").where(eq("id",6) ).build()
  • C.Builder&lt;?&gt; 工作..

标签: java generics design-patterns


【解决方案1】:

由于C.Builder 的参数T 必须是扩展C.Builder 的东西,因此您必须创建另一个扩展C.Builder 的类,因为您不能使用C.Builder 本身,因为它是参数化的。

因此,对于继承的构建器,一种解决方案是创建两个构建器,一个是通用的、可扩展的、受保护的和抽象的,另一个是公共的、最终的且不用于实际构建的通用构建器。

以下是显示这一点的示例类:

public class Person {
  private final String name;

  public Person(String name) {
    this.name = name;
  }

  public String getName() {
    return name;
  }

  protected static abstract class ExtensiblePersonBuilder<S, T extends Person> {
    protected String name;

    public S name(String name) {
      this.name = name;
      return self();
    }

    public abstract S self();
    public abstract T build();
  }

  public static final class PersonBuilder extends ExtensiblePersonBuilder<PersonBuilder, Person> {
    @Override
    public PersonBuilder self() {
      return this;
    }

    @Override
    public Person build() {
      return new Person(name);
    }
  }
}

还有一个子类,带有构建器:

  public class Employee extends Person {
    private int number;

    public Employee(String name, int number) {
      super(name);

      this.number = number;
    }

    protected static abstract class ExtensibleEmployeeBuilder<S, T extends Employee> extends ExtensiblePersonBuilder<S, T> {
      protected int number;

      public S number(int number) {
        this.number = number;
        return self();
      }
    }

    public static final class EmployeeBuilder extends ExtensibleEmployeeBuilder<EmployeeBuilder, Employee> {

      @Override
      public EmployeeBuilder self() {
        return this;
      }

      @Override
      public Employee build() {
        return new Employee(name, number);
      }
    }
  }

还有一个子子类:

public class Manager extends Employee {
  private String teamName;

  public Manager(String name, int number, String teamName) {
    super(name, number);

    this.teamName = teamName;
  }

  protected static abstract class ExtensibleManagerBuilder<S, T extends Manager> extends ExtensibleEmployeeBuilder<S, T> {
    protected String teamName;

    public S teamName(String teamName) {
      this.teamName = teamName;
      return self();
    }
  }

  public static final class ManagerBuilder extends ExtensibleManagerBuilder<ManagerBuilder, Manager> {
    @Override
    public ManagerBuilder self() {
      return this;
    }

    @Override
    public Manager build() {
      return new Manager(name, number, teamName);
    }
  }
}

您可以像这样使用这些构建器:

Person p = new PersonBuilder().name("John").build();

或:

Manager m = new ManagerBuilder().name("Jeff").teamName("X").number(2).build();

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-08-28
    相关资源
    最近更新 更多