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

如何设计API以支持用户修改次要配置选项?默认无需改动可未来调整

这是个非常典型的API设计痛点——既要让大部分用户用起来省心(默认配置搞定一切),又要给有特殊需求的用户留好调整的入口,还不能让API显得臃肿混乱。我来分享几个在实际项目中验证过的方案:

方案1:Builder模式(最推荐)

Builder模式简直是为这种场景量身定做的。核心思路是把所有配置项(包括次要的)都封装在一个Builder类里,默认值提前设置好,用户只需要修改关心的选项,最后通过Builder生成核心对象。

举个例子:

// 核心API类,保持简洁,构造函数私有
public class SomeComplicatedMessageInterpretter
{
    public bool ShouldReturnPartialResults { get; }
    public int MaxRetryCount { get; }
    // 其他核心属性...

    // 私有构造,只能通过Builder创建
    private SomeComplicatedMessageInterpretter(Builder builder)
    {
        ShouldReturnPartialResults = builder.ShouldReturnPartialResults;
        MaxRetryCount = builder.MaxRetryCount;
    }

    // 公开的Builder类,放在核心类内部,用户一眼就能找到
    public class Builder
    {
        // 次要配置的默认值在这里设置
        public bool ShouldReturnPartialResults { get; set; } = false;
        public int MaxRetryCount { get; set; } = 3;

        // 链式调用的设置方法,语义更清晰
        public Builder WithPartialResultsEnabled(bool enabled)
        {
            ShouldReturnPartialResults = enabled;
            return this;
        }

        public Builder WithMaxRetryCount(int count)
        {
            MaxRetryCount = count;
            return this;
        }

        // 生成核心对象的方法
        public SomeComplicatedMessageInterpretter Build()
        {
            return new SomeComplicatedMessageInterpretter(this);
        }
    }

    // 给用户一个快捷创建入口(用默认配置)
    public static SomeComplicatedMessageInterpretter CreateDefault()
    {
        return new Builder().Build();
    }
}

用户使用的时候,要么直接用默认:

var interpreter = SomeComplicatedMessageInterpretter.CreateDefault();

要么按需修改:

var interpreter = new SomeComplicatedMessageInterpretter.Builder()
    .WithPartialResultsEnabled(true)
    .WithMaxRetryCount(5)
    .Build();

这种方式的好处是:用户不用找零散的配置类,Builder和核心类绑定在一起,语义清晰;默认值集中管理,API不会因为一堆可选参数显得杂乱。

方案2:带可选参数的静态工厂方法

如果你的场景比较简单,不想引入Builder类,那可以用可选参数的静态工厂方法。把次要配置项作为可选参数,设置好默认值,用户只需要传需要修改的参数。

示例:

public class SomeComplicatedMessageInterpretter
{
    public bool ShouldReturnPartialResults { get; }
    public int MaxRetryCount { get; }

    public SomeComplicatedMessageInterpretter(bool shouldReturnPartialResults = false, int maxRetryCount = 3)
    {
        ShouldReturnPartialResults = shouldReturnPartialResults;
        MaxRetryCount = maxRetryCount;
    }

    // 或者用静态工厂方法,把构造函数设为私有
    public static SomeComplicatedMessageInterpretter Create(bool shouldReturnPartialResults = false, int maxRetryCount = 3)
    {
        return new SomeComplicatedMessageInterpretter(shouldReturnPartialResults, maxRetryCount);
    }
}

用户使用:

// 默认配置
var interpreter = SomeComplicatedMessageInterpretter.Create();
// 修改单个次要配置
var interpreter = SomeComplicatedMessageInterpretter.Create(maxRetryCount: 5);

这个方案的缺点是如果次要配置项太多,参数列表会很长,可读性下降。适合配置项少的场景。

方案3:独立配置类+扩展方法

如果次要配置项很多,或者未来可能还要扩展,那可以把所有次要配置抽成一个独立的配置类,然后给核心API类加一个扩展方法或者接受配置类的构造/工厂方法。

示例:

// 独立的配置类,所有次要选项在这里,默认值在构造函数里
public class MessageInterpretterConfig
{
    public bool ShouldReturnPartialResults { get; set; } = false;
    public int MaxRetryCount { get; set; } = 3;
    public TimeSpan Timeout { get; set; } = TimeSpan.FromSeconds(10);
    // 更多配置项...
}

public class SomeComplicatedMessageInterpretter
{
    private readonly MessageInterpretterConfig _config;

    // 默认构造用默认配置
    public SomeComplicatedMessageInterpretter()
        : this(new MessageInterpretterConfig())
    {
    }

    // 接受自定义配置的构造
    public SomeComplicatedMessageInterpretter(MessageInterpretterConfig config)
    {
        _config = config ?? throw new ArgumentNullException(nameof(config));
    }
}

// 可以加个扩展方法,让调用更流畅
public static class SomeComplicatedMessageInterpretterExtensions
{
    public static SomeComplicatedMessageInterpretter WithConfig(this SomeComplicatedMessageInterpretter _, MessageInterpretterConfig config)
    {
        return new SomeComplicatedMessageInterpretter(config);
    }
}

用户使用:

// 默认配置
var interpreter = new SomeComplicatedMessageInterpretter();
// 自定义配置
var config = new MessageInterpretterConfig
{
    MaxRetryCount = 5,
    Timeout = TimeSpan.FromSeconds(15)
};
var interpreter = new SomeComplicatedMessageInterpretter(config);

这种方案的好处是配置可以复用,适合多个核心对象需要相同配置的场景。

额外的优化建议
  • 文档注释要到位:在核心API类的注释里明确提到“如需修改次要配置,请使用Builder/Config类”,并且给配置类和每个配置项加上详细的注释,说明用途和默认值。
  • 保持配置不可变:如果可能的话,把配置类的属性设为只读,只能通过构造函数或者Builder来修改,避免用户在运行时意外修改配置导致的问题。
  • 提供默认配置实例:可以在配置类里加一个静态的Default属性,比如public static MessageInterpretterConfig Default => new MessageInterpretterConfig();,方便用户基于默认配置修改。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.22 09:29:27