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

获取图表数据序列时,最佳设计模式选型及代码架构优化咨询

后端图表数据API的代码组织方案

1. 明确分层职责,拆解现有逻辑

把当前Controller直接调用Repository+计算函数的结构拆为四层,保证职责单一:

  • Controller层:仅负责接收请求、参数校验、调用Service返回响应,不处理任何业务逻辑或数据计算。
  • Service层:作为业务逻辑核心,负责编排数据流程——调用Repository获取原始数据,根据需求选择是否触发计算逻辑,最终返回可直接用于图表的序列。
  • Repository层:只做数据库交互,执行SQL查询返回原始数据模型,不做任何数据转换或计算。
  • Calculator层:将所有数据计算逻辑抽为独立的类/函数集合,每个计算逻辑对应一个独立方法(比如calculateGrowthRate、computeMovingAverage),专注纯数据运算,不依赖数据库或业务上下文。

2. 用设计模式简化逻辑扩展

策略模式(Strategy Pattern)

如果存在多种数据计算规则(比如不同图表需要不同的增长率、平均值计算),把每种计算逻辑封装成独立策略类,统一实现一个通用接口:

// 通用计算策略接口
public interface DataCalculationStrategy {
    List<Double> calculate(List<Double> rawData);
}

// 具体策略:计算移动平均值
public class MovingAverageStrategy implements DataCalculationStrategy {
    private int windowSize;
    public MovingAverageStrategy(int windowSize) {
        this.windowSize = windowSize;
    }
    @Override
    public List<Double> calculate(List<Double> rawData) {
        // 移动平均计算逻辑实现
    }
}

// 具体策略:计算同比增长率
public class YoYGrowthStrategy implements DataCalculationStrategy {
    @Override
    public List<Double> calculate(List<Double> rawData) {
        // 同比增长率计算逻辑实现
    }
}

Service层根据请求参数(比如图表类型)选择对应策略,避免大量if-else判断。

工厂模式(Factory Pattern)

配合策略模式,用工厂类创建具体的计算策略实例,Service层只需调用工厂获取策略,无需关心具体实现:

public class CalculationStrategyFactory {
    public static DataCalculationStrategy getStrategy(String chartType) {
        return switch(chartType) {
            case "MOVING_AVERAGE" -> new MovingAverageStrategy(7);
            case "YOY_GROWTH" -> new YoYGrowthStrategy();
            default -> throw new IllegalArgumentException("不支持的图表类型");
        };
    }
}

装饰器模式(Decorator Pattern)

如果需要对同一组原始数据执行多步连续计算(比如先算增长率再做数据平滑),用装饰器模式叠加计算逻辑,避免硬编码步骤:

public abstract class DataCalculationDecorator implements DataCalculationStrategy {
    protected DataCalculationStrategy wrappedStrategy;
    public DataCalculationDecorator(DataCalculationStrategy wrappedStrategy) {
        this.wrappedStrategy = wrappedStrategy;
    }
}

// 装饰器:对计算结果做平滑处理
public class SmoothingDecorator extends DataCalculationDecorator {
    public SmoothingDecorator(DataCalculationStrategy wrappedStrategy) {
        super(wrappedStrategy);
    }
    @Override
    public List<Double> calculate(List<Double> rawData) {
        List<Double> calculatedData = wrappedStrategy.calculate(rawData);
        // 对计算结果做平滑处理
        return smoothedData;
    }
}

使用时可自由组合:new SmoothingDecorator(new YoYGrowthStrategy()),实现先算增长率再平滑的链式操作。

3. 代码拆分的具体实践

  • 按业务领域拆分Repository:比如UserBehaviorRepository、SalesDataRepository,每个类仅负责对应领域的SQL查询。
  • 按计算类型分组Calculator:比如TrendCalculators、StatisticCalculators类,每个类下存放同类型的计算方法。
  • 按图表场景拆分Service:比如SalesChartService、UserEngagementChartService,每个Service仅负责一类图表的数据组装逻辑。

4. 额外优化点

  • 将常用计算参数(比如移动平均窗口大小)抽入配置文件(如application.yml),避免硬编码。
  • 为计算逻辑添加单元测试,纯数据运算易写测试用例,能有效保证计算结果准确性。
  • 若计算逻辑耗时较长,对重复计算的结果做缓存(如用Redis),避免每次请求重复计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 09:50:43