You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java递归泛型实现管道模式Fluent API泛型同步问题求解

递归泛型实现分层Fluent管道API的类型传递问题

预期实现效果

我正在尝试实现符合管道模式的分层Fluent API(流畅接口),该接口由一系列段(segment)、操作(operation)顺序组成,前一个操作的输出将作为下一个操作的输入,期望实现的调用形式如下:

Pipeline<String> pipeline = Pipeline<String>.newPipe()
    .segments()
        .segment()
            .operation()
                .op(new Operation()) // from String to Integer
                .someConfiguration()...
            .done()
            .operation()
                .op(new Operation2()) // from Integer to Map
                .someConfiguration()...
            .done()
            .segments()
                .segment()
                    .operation()
                        .....
                    .end()
                    ...
                .done()
                .segment()
                    ....
                .done()
            .done()
        .done()
    .done()
.build();

初始实现代码

我尝试基于递归泛型实现该能力,首先定义了Base基类:

public class Base<U, S, T extends Base<S, ?, ?>> {

}

基于该基类实现的各子类代码如下:

public class Segments<U, S, T extends Base<S, ?, ?>> extends Base<U, S, T> {

    private T parent;

    public Segments(T parent) {
        this.parent = parent;
    }

    public Segment<U, U, Segments<U, S, T>> segment() {
        return new Segment<>(this);
    }

    public <A> Segments<A, S, T> returns(String expression, Class<A> clazz) {
        return (Segments<A, S, T>) this;
    }

    public T done() {
        return parent;
    }

}

public class Segment<U, S, T extends Base<S, ?, ?>> extends Base<U, S, T> {

    private Op<U, U, Segment<U, S, T>> op;

    private Segments<U, U, Segment<U, S, T>> segments;

    private T parent;

    public Segment(T parent) {
        this.parent = parent;
        this.segments = new Segments<>(this);
        this.op = new Op<>(this);
    }

    public Op<U, U, Segment<U, S, T>> op() {
        return op;
    }

    public Segments<U, U, Segment<U, S, T>> segments() {
        return this.segments;
    }

    public <A> Segment<A, S, T> returns(String expression, Class<A> clazz) {
        return (Segment<A, S, T>) this;
    }

    public T done() {
        return parent;
    }

}


public class Op<U, S, T extends Base<S, ?, ?>> extends Base<U, S, T> {

    private Supplier<Step> step;

    private T parent;

    public Op(T parent) {
        this.parent = parent;
    }

    public <OUT> Op<OUT, OUT, T> op(Supplier<Step<U, OUT>> operation) {
        this.step = (Supplier) operation;
        return (Op<OUT, OUT, T>) this;
    }

    public <A> Op<A, S, T> returns(String expression, Class<A> clazz) {
        return (Op<A, S, T>) this;
    }

    public T done() {
        return parent;
    }

}

public interface Step<IN, OUT> {

    OUT execute(IN object);
    
}

泛型参数定义

  • U:当前节点的输入类型
  • S:父节点的输入类型
  • T:父节点引用

遇到的问题

该设计的目标是:操作定义完成后,父节点(Segment)的输入泛型U可根据操作的输出类型OUT(即Op的U泛型)同步更新。该逻辑在Op类中通过(Op<OUT, OUT, T>) this强制类型转换实现,但目前T泛型在实例创建时即固定,无法随类型变更同步更新,导致类型传递失效。

我曾尝试调整done()方法的返回值,不返回泛型T,而是返回通配符定义的父类型,代码如下:

public Segment<S, ?, ?> done() {
    return parent;
}

该方式虽解决了类型变更问题,但会丢失所有祖先节点的泛型信息,而这些信息是保证全管道类型一致性的必要条件。

待解决问题

如何在保留递归泛型设计的前提下解决该问题?


内容的提问来源于stack exchange,提问作者quleb

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.27 17:30:48