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

如何为消息发送器构建Fluent API?

实现无依赖的消息发送器Fluent API方案

方案1:让Builder直接持有Publisher,消除循环依赖

你可以将MessagePublisher直接注入MessageBuilder,让MessageSender仅负责创建Builder并传递Publisher,这样就避免了Builder对MessageSender的依赖:

public class MessageSender {
    private final MessagePublisher publisher;

    public MessageSender(MessagePublisher publisher) {
        this.publisher = publisher;
    }

    public MessageBuilder newMessage() {
        return new MessageBuilder(publisher);
    }
}

public class MessageBuilder {
    private final MessagePublisher publisher;
    private final Message message = new Message();

    public MessageBuilder(MessagePublisher publisher) {
        this.publisher = publisher;
    }

    public MessageBuilder withSomeField(String value) {
        message.setSomeField(value);
        return this;
    }

    public MessageBuilder withAnotherField(String value) {
        message.setAnotherField(value);
        return this;
    }

    public void publish() {
        publisher.publish(message);
    }
}

这种设计下,MessageBuilder只依赖MessagePublisher,和MessageSender没有绑定关系,彻底消除了你反感的循环依赖。

方案2:分离构建与发送,用终结器衔接

如果不想让Builder持有Publisher,可以把构建和发送拆分为两个独立步骤,通过MessageSender提供的发送方法完成最终操作:

public class MessageSender {
    private final MessagePublisher publisher;

    public MessageSender(MessagePublisher publisher) {
        this.publisher = publisher;
    }

    public MessageBuilder newMessage() {
        return new MessageBuilder();
    }

    public void publish(Message message) {
        publisher.publish(message);
    }

    public class MessageBuilder {
        private final Message message = new Message();

        public MessageBuilder withSomeField(String value) {
            message.setSomeField(value);
            return this;
        }

        public MessageBuilder withAnotherField(String value) {
            message.setAnotherField(value);
            return this;
        }

        public Message build() {
            return message;
        }
    }
}

调用方式会变成:

Message message = messageSender.newMessage()
    .withSomeField("some value")
    .withAnotherField("some value")
    .build();
messageSender.publish(message);

如果仍想保留链式调用的体验,也可以在Builder中添加publish方法,让它调用外部MessageSender的发送逻辑,这是单向依赖而非循环依赖:

// 在MessageBuilder中新增
public void publish() {
    MessageSender.this.publish(message);
}

方案3:静态Builder+全局Publisher入口(适合简单场景)

如果你的MessagePublisher是单例或可全局获取,可以用静态Builder实现无实例化调用:

public class MessageSender {
    private static MessagePublisher publisher;

    public static void init(MessagePublisher publisher) {
        MessageSender.publisher = publisher;
    }

    public static MessageBuilder newMessage() {
        return new MessageBuilder();
    }

    public static class MessageBuilder {
        private final Message message = new Message();

        public MessageBuilder withSomeField(String value) {
            message.setSomeField(value);
            return this;
        }

        public MessageBuilder withAnotherField(String value) {
            message.setAnotherField(value);
            return this;
        }

        public void publish() {
            publisher.publish(message);
        }
    }
}

这种方式不需要实例化MessageSender,但依赖全局状态,仅适合小型或简单项目。


内容的提问来源于stack exchange,提问作者Jakub Znamenáček

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.09 10:24:54