递归泛型(Self-Type)Builder模式

核心问题

`// ❌ 错误示例
class BaseBuilder {
BaseBuilder name(String name) { return this; }
}

class SubBuilder extends BaseBuilder {
SubBuilder age(int age) { return this; }
}

// 问题:返回类型是 BaseBuilder,无法调用 age()
new SubBuilder().name("张三").age(20); // 编译错误!
`

解决方案
`// ✅ 正确示例
abstract class Builder<T extends Builder> {
protected abstract T self(); // 返回子类自身类型

public T name(String name) {
    this.name = name;
    return self(); // 返回子类类型
}

}

class SubBuilder extends Builder {
@Override
protected SubBuilder self() {
return this; // 返回自己
}

public SubBuilder age(int age) {
    this.age = age;
    return this;
}

}

// 完美链式调用
new SubBuilder().name("张三").age(20).build(); // ✅ 编译通过
`

`public abstract static class Builder<T extends Builder> {
protected String project;
protected String summary;
protected String description;
protected String issueType;
protected String assignee;

    public T project(String project) {
        this.project = project;
        return self();
    }

    public T summary(String summary) {
        this.summary = summary;
        return self();
    }

    public T description(String description) {
        this.description = description;
        return self();
    }

    public T issueType(String issueType) {
        this.issueType = issueType;
        return self();
    }

    public T assignee(String assignee) {
        this.assignee = assignee;
        return self();
    }

    protected abstract T self();
    public abstract BaseIssueRequest build();
}`

Java代码建造者模式抽象基类设计解读

这段Java代码是一个典型的建造者模式(Builder Pattern) 抽象基类设计,专门用于分步构建包含项目、摘要等属性的BaseIssueRequest对象,且通过泛型保证了子类实现时的类型安全。下面我会逐部分拆解,让你清晰理解每一行的作用和整体设计思路。

一、整体功能总结

这段代码定义了一个抽象的静态内部Builder类,核心目的是封装BaseIssueRequest对象的属性设置过程,通过“链式调用”的方式让对象构建更灵活、可读性更高;同时通过抽象方法约束子类必须实现具体的“返回自身实例”和“构建最终对象”的逻辑。

二、逐部分代码解读

1. 类定义:public abstract static class Builder<T extends Builder<T>>

public abstract static class Builder<T extends Builder<T>> {
  • public:该类对外可见,外部可以访问这个Builder类;
  • abstract:抽象类,不能直接实例化,必须由子类继承并实现其中的抽象方法;
  • static:静态内部类,意味着这个Builder类不依赖外部类的实例,可直接通过“外部类.Builder”的方式使用(比如OuterClass.Builder);
  • <T extends Builder<T>>递归泛型(F-bounded泛型),这是这段代码的核心设计技巧:
    • 约束泛型T必须是Builder的子类;
    • 目的是让子类Builder调用project()summary()等方法时,返回的是子类自身类型(而非父类Builder),保证链式调用的类型安全。

2. 成员变量:

protected String project;
protected String summary;
protected String description;
protected String issueType;
protected String assignee;
  • protected:保护访问权限,既保证封装性(外部类不能直接访问),又允许子类直接使用这些属性;
  • 这些变量对应最终要构建的BaseIssueRequest对象的核心属性:项目(project)、摘要(summary)、问题描述(description)、问题类型(issueType)、经办人(assignee)。

3. 属性设置方法(链式调用核心):

project()方法为例,其他summary()description()等方法逻辑完全一致:

public T project(String project) {
    this.project = project;
    return self();
}
  • 方法作用:接收外部传入的project值,赋值给当前Builder对象的project成员变量;
  • 返回值:返回泛型T类型(子类Builder),实现链式调用(比如builder.project("proj1").summary("test").build());
  • self():调用抽象方法self(),由子类实现返回“自身实例”,这是递归泛型能生效的关键。

4. 抽象方法(约束子类实现):

protected abstract T self();
public abstract BaseIssueRequest build();
  • protected abstract T self()
    • 抽象方法,子类必须实现;
    • 作用:返回当前Builder子类的实例(通常子类直接返回this),解决父类无法知道子类具体类型的问题,保证链式调用返回子类类型;
  • public abstract BaseIssueRequest build()
    • 抽象方法,子类必须实现;
    • 作用:将Builder中设置的所有属性组装成最终的BaseIssueRequest对象并返回,是建造者模式的“产品构建”核心方法。

三、使用示例(帮助理解子类实现和调用)

为了让你更直观理解,我补充一个子类实现和调用的完整示例:

// 子类继承抽象Builder,指定泛型为自身
public class IssueRequestBuilder extends Builder<IssueRequestBuilder> {
    // 实现self()方法,返回当前子类实例
    @Override
    protected IssueRequestBuilder self() {
        return this; // 关键:返回自身,保证链式调用类型正确
    }

    // 实现build()方法,构建最终的BaseIssueRequest对象
    @Override
    public BaseIssueRequest build() {
        BaseIssueRequest request = new BaseIssueRequest();
        // 将Builder中设置的属性赋值给最终对象
        request.setProject(this.project);
        request.setSummary(this.summary);
        request.setDescription(this.description);
        request.setIssueType(this.issueType);
        request.setAssignee(this.assignee);
        return request;
    }
}

// 调用示例
public class Test {
    public static void main(String[] args) {
        // 链式调用构建对象,代码简洁易读
        BaseIssueRequest request = new IssueRequestBuilder()
                .project("PROJ-001")       // 设置项目
                .summary("登录功能异常")    // 设置摘要
                .description("密码正确但无法登录") // 设置描述
                .issueType("Bug")          // 设置问题类型
                .assignee("zhangsan")      // 设置经办人
                .build();                  // 构建最终对象
    }
}

总结

  1. 核心设计模式:采用建造者模式,将复杂对象(BaseIssueRequest)的构建过程拆分,支持分步设置属性,且链式调用让代码更简洁;
  2. 泛型技巧:递归泛型<T extends Builder<T>>保证子类链式调用时返回自身类型,避免类型强转;
  3. 抽象约束self()build()抽象方法强制子类实现核心逻辑,保证建造者模式的规范性和扩展性。

简单来说,这段代码是为“构建包含项目、摘要等属性的问题请求对象”设计的通用抽象构建器,子类只需实现少量代码就能完成具体对象的构建。

posted @ 2025-12-10 09:36  琅琊甲乙木  阅读(1)  评论(0)    收藏  举报