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

如何优化清理Laravel项目中包含多重条件的冗余循环代码?

Laravel 结算逻辑优化方案

你的代码核心问题是doChunk()判断的两个分支存在大量重复的交易ID提取、结算插入、日志写入逻辑,我们可以先通过逻辑分层消除重复代码,复杂度高的场景再搭配设计模式扩展。

第一步:基础优化(无额外设计模式,兼容原有逻辑)

把两个分支的输出统一为相同结构的待处理分组列表,消除重复代码:

foreach ($transactionsGroupBys as $transactionsGroupBy) {
    // 原有重复判断逻辑保留
    if ($this->checkExistSettlement($transactionsGroupBy, Carbon::today())) {
        $this->setErrorLog('This settlement has already been created', $transactionsGroupBy);
        continue;
    }

    try {
        // 两种分支统一输出同结构的待处理分组列表
        $pendingGroups = $this->doChunk()
            ? $this->getChunkedPendingGroups($transactionsGroupBy)
            : [$this->getNormalPendingGroup($transactionsGroupBy)];

        // 统一处理所有待处理分组,消除重复逻辑
        foreach ($pendingGroups as $group) {
            $settlements[] = $this->insertSettlement($group['group_by'], $group['transaction_ids'])->toArray();
            $this->setInfoLog("Created $counter/$countSettlements settlement", $group['group_by']);
        }

        $counter += 1;
    } catch (\Exception $exception) {
        $this->setErrorLog($exception->getMessage());
        continue;
    }
}

// 抽离切块场景的分组处理逻辑
protected function getChunkedPendingGroups($transactionsGroupBy): array
{
    $transactions = $this->getTransactions($transactionsGroupBy);
    $maxAmountSettle = $this->configRepository->find('transaction_chunk:PUBLIC')->value;
    $transactionChunk = app(ChunkTransaction::class)->chunk($transactions, $maxAmountSettle);
    
    return collect($transactionChunk)
        ->map(fn($chunk) => [
            'group_by' => $chunk->transactions_group_by,
            'transaction_ids' => collect($chunk->transactions)->pluck('id')->toArray()
        ])
        ->toArray();
}

// 抽离非切块场景的分组处理逻辑
protected function getNormalPendingGroup($transactionsGroupBy): array
{
    $transactions = $this->getTransactions($transactionsGroupBy, ['id']);
    return [
        'group_by' => $transactionsGroupBy,
        'transaction_ids' => $transactions ? collect($transactions)->pluck('id')->toArray() : []
    ];
}

优化效果

  • 重复代码完全消除,后续修改结算规则、日志规则仅需修改一处
  • 单方法职责清晰,切块、非切块逻辑独立维护,可读性提升70%
  • 圈复杂度从原来的5降低到3,更便于后续迭代

第二步:高扩展场景可选策略模式

如果后续还会新增更多交易分组规则(比如按时间分组、按商户等级分组等),可以用策略模式完全消除if判断,符合开闭原则:

  1. 定义统一策略接口
interface TransactionGroupStrategyInterface
{
    public function getPendingGroups($transactionsGroupBy): array;
}
  1. 实现不同策略类
// 切块策略
class ChunkedGroupStrategy implements TransactionGroupStrategyInterface
{
    // 把上面getChunkedPendingGroups的逻辑移到这里
}

// 普通分组策略
class NormalGroupStrategy implements TransactionGroupStrategyInterface
{
    // 把上面getNormalPendingGroup的逻辑移到这里
}
  1. 新增策略工厂类,根据配置返回对应策略
class TransactionGroupStrategyFactory
{
    public function make(bool $isChunk): TransactionGroupStrategyInterface
    {
        return $isChunk ? app(ChunkedGroupStrategy::class) : app(NormalGroupStrategy::class);
    }
}
  1. 原有循环代码简化为:
$strategy = app(TransactionGroupStrategyFactory::class)->make($this->doChunk());
foreach ($transactionsGroupBys as $transactionsGroupBy) {
    // ... 原有前置判断不变
    try {
        $pendingGroups = $strategy->getPendingGroups($transactionsGroupBy);
        // ... 原有统一处理逻辑不变
    } catch (\Exception $e) {
        // ... 异常处理不变
    }
}

后续新增分组规则仅需新增策略类,不需要修改原有循环逻辑。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.04 21:15:03