java - 构建器模式和扩展自身的泛型类型

标签 java generics design-patterns

我正在尝试使用继承实现 Builder 模式,并发现以下 solution .

这是B类(class):

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<>();

最佳答案

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

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

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

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();

关于java - 构建器模式和扩展自身的泛型类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62133241/

相关文章:

java - Camel 的completionSize和completionTimeout在JUnit中无法正常工作

java - 为什么 Map<String, int> list = new HashMap<String, int> 是不允许的?

design-patterns - 我们什么时候才能像 J2EE 那样期待来自 SUN/Oracle 的 Core Java EE Patterns?

c# - C# 标志枚举中的私有(private)值

java - 记录 TestNG 测试用例

java - Android 堆增长 - 我应该担心吗?

c# - C#(或C++)与JAVA之间如何通信

c# - 在 C# 中将 List<anonymous type> 传递到需要 List<T> 的方法中

swift - 为泛型类型参数声明类型别名的目的是什么

php - 清洁架构中的记录器