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

设计模式问题:如何重构过度使用布尔参数的文件上传函数?

重构方案

1. 封装可变配置项,替换零散布尔参数

首先将所有控制执行逻辑的标志参数封装为独立的UploadConfig配置类,使用构造器模式(Builder)实现实例化,既保留参数默认值兼容旧调用,也大幅提升调用处的可读性:

// 配置类示例
public class UploadConfig {
    private final boolean ignoreAzure;
    private final boolean ignoreAws;
    private final boolean logToAirtable;

    private UploadConfig(Builder builder) {
        this.ignoreAzure = builder.ignoreAzure;
        this.ignoreAws = builder.ignoreAws;
        this.logToAirtable = builder.logToAirtable;
    }

    public static class Builder {
        // 默认值可根据通用场景设定
        private boolean ignoreAzure = false;
        private boolean ignoreAws = false;
        private boolean logToAirtable = false;

        public Builder ignoreAzure(boolean val) {
            ignoreAzure = val;
            return this;
        }

        public Builder ignoreAws(boolean val) {
            ignoreAws = val;
            return this;
        }

        public Builder logToAirtable(boolean val) {
            logToAirtable = val;
            return this;
        }

        public UploadConfig build() {
            return new UploadConfig(this);
        }
    }

    // 仅提供getter方法,保证配置不可变
    public boolean isIgnoreAzure() { return ignoreAzure; }
    public boolean isIgnoreAws() { return ignoreAws; }
    public boolean isLogToAirtable() { return logToAirtable; }
}

改造后的方法签名如下,新增配置项时只需修改配置类,无需改动方法签名:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes, UploadConfig config)

2. 拆分执行步骤,固定执行顺序

将原有函数内的每个功能段拆分为独立的步骤实现,统一实现UploadStep接口,内部自行判断是否需要执行:

public interface UploadStep {
    // 判断当前步骤是否需要执行
    boolean shouldExecute(UploadConfig config);
    // 执行步骤逻辑
    void execute(long userId, long locationId, byte[] fileBytes, UploadConfig config);
}

// 示例步骤:Azure上传
public class AzureUploadStep implements UploadStep {
    @Override
    public boolean shouldExecute(UploadConfig config) {
        return !config.isIgnoreAzure();
    }

    @Override
    public void execute(long userId, long locationId, byte[] fileBytes, UploadConfig config) {
        // 原有Azure上传逻辑
    }
}

// 其他步骤(AWS上传、Airtable日志等)同理实现

在uploadThing内部按要求的固定顺序维护步骤列表,遍历执行即可:

public ResponseObject uploadThing(long user_id, long location_id, byte[] file_bytes, UploadConfig config) {
    // 固定执行顺序,新增步骤只需在此处添加即可
    List<UploadStep> steps = List.of(
        new AzureUploadStep(),
        new AwsUploadStep(),
        new AirtableLogStep()
    );

    for (UploadStep step : steps) {
        if (step.shouldExecute(config)) {
            step.execute(user_id, location_id, file_bytes, config);
        }
    }

    // 原有返回逻辑
    return new ResponseObject();
}

3. 调用示例

调用处代码可读性大幅提升,无需记忆参数顺序:

// 原有调用:ro = uploadThing(user_id, org_id, file_bytes, true, false, true)
// 改造后调用
UploadConfig config = new UploadConfig.Builder()
    .ignoreAzure(true)
    .ignoreAws(false)
    .logToAirtable(true)
    .build();
ro = uploadThing(user_id, org_id, file_bytes, config);

4. 可选优化:封装场景化快捷方法

如果存在固定的通用调用场景,可以额外封装对应场景的静态方法,进一步降低调用方的使用成本:

// 示例:内部系统上传场景,默认忽略AWS、打Airtable日志
public static ResponseObject uploadForInternal(long user_id, long location_id, byte[] file_bytes) {
    UploadConfig config = new UploadConfig.Builder()
        .ignoreAws(true)
        .logToAirtable(true)
        .build();
    return uploadThing(user_id, location_id, file_bytes, config);
}

调用方直接调用uploadForInternal即可,完全不需要关心内部配置细节,意图清晰。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.24 10:06:03