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

如何重构包含重复代码的UpFirst()与RightFirst()函数?

重构方案:消除UpFirst和RightFirst的重复代码

核心思路

通过提取公共逻辑和参数化差异部分,将两个高度重复的函数拆分为通用框架+专用逻辑,大幅提升代码可读性和可维护性。


步骤1:定义方向枚举(区分上下/左右检查)

创建枚举标记检查方向,让通用方法能区分不同处理逻辑:

private enum CheckDirection
{
    Up,
    Right
}

步骤2:提取公共匹配组处理逻辑

将两个函数中if(isAllMatch)块内的重复代码抽离为独立方法,同时优化匹配类型的判断顺序(减少嵌套):

private void ProcessMatchGroup(int x, int y, List<Tiles> sameBlocks)
{
    sameBlocks.Add(_tiles[x, y]);
    var newBlocks = FloodFill(x, y);
    
    // 合并新找到的块
    foreach (var block in newBlocks.Where(block => !sameBlocks.Contains(block)))
    {
        sameBlocks.Add(block);
    }
    
    // 确定匹配组类型(从严格到宽松判断,避免嵌套)
    var matchType = TileGroupType.Default;
    if (sameBlocks.Count > _ConditionCCount)
    {
        matchType = TileGroupType.C;
    }
    else if (sameBlocks.Count > _ConditionBCount)
    {
        matchType = TileGroupType.B;
    }
    else if (sameBlocks.Count > _ConditionACount)
    {
        matchType = TileGroupType.A;
    }
    
    // 设置所有匹配块的类型
    foreach (var block in sameBlocks)
    {
        block.SetMatchGroupType(matchType);
    }
}

步骤3:提取连续匹配判断逻辑

将检查连续同色块的逻辑抽离,通过方向参数适配上下/左右的检查方式:

private bool HasConsecutiveMatches(int x, int y, CheckDirection direction)
{
    var currentBlock = _tiles[x, y];
    
    for (var i = 1; i < _MinNumberToBlast; i++)
    {
        Tiles blockToCheck;
        switch (direction)
        {
            case CheckDirection.Up:
                blockToCheck = _tiles[x, y + i];
                break;
            case CheckDirection.Right:
                blockToCheck = _tiles[x + i, y];
                break;
            default:
                throw new ArgumentOutOfRangeException(nameof(direction));
        }
        
        // 只要有一个块不匹配,直接终止检查
        if (currentBlock.Color != blockToCheck.Color)
        {
            return false;
        }
    }
    
    return true;
}

步骤4:创建通用检查方法

将循环框架、跳过条件、方向相关的差异逻辑整合到通用方法中:

private bool CheckMatches(CheckDirection direction)
{
    var sameBlocks = new List<Tiles>();
    var isAnyMatch = false;
    
    switch (direction)
    {
        case CheckDirection.Up:
            for (var x = 0; x < _RowCount; x++)
            {
                for (var y = 0; y < _ColumnCount; y++)
                {
                    // 跳过无法形成最小匹配的位置
                    if (y > _ColumnCount - _MinNumberToBlast)
                        continue;
                    
                    if (HasConsecutiveMatches(x, y, direction))
                    {
                        isAnyMatch = true;
                        ProcessMatchGroup(x, y, sameBlocks);
                    }
                    
                    sameBlocks.Clear();
                }
            }
            break;
        
        case CheckDirection.Right:
            for (var y = 0; y < _ColumnCount; y++)
            {
                for (var x = 0; x < _RowCount; x++)
                {
                    // 跳过无法形成最小匹配的位置
                    if (x > _RowCount - _MinNumberToBlast)
                        continue;
                    
                    // RightFirst独有的初始化操作
                    var currentBlock = _tiles[x, y];
                    currentBlock.SetMatchGroupType(TileGroupType.Default);
                    
                    if (HasConsecutiveMatches(x, y, direction))
                    {
                        isAnyMatch = true;
                        ProcessMatchGroup(x, y, sameBlocks);
                    }
                    
                    sameBlocks.Clear();
                }
            }
            break;
        
        default:
            throw new ArgumentOutOfRangeException(nameof(direction));
    }
    
    return isAnyMatch;
}

步骤5:简化原方法

原有两个函数只需调用通用方法即可,代码简洁明了:

private bool UpFirst()
{
    return CheckMatches(CheckDirection.Up);
}

private bool RightFirst()
{
    return CheckMatches(CheckDirection.Right);
}

额外优化点(可选)

  • 原代码中sameBlocks.Contains(block)的时间复杂度是O(n),如果FloodFill返回的集合较大,建议用HashSet<Tiles>代替List<Tiles>来提升性能。
  • 可以将ProcessMatchGroup中的sameBlocks改为方法内创建,避免外部传入带来的状态管理问题。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 13:50:25