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

含重复逻辑的条件语句与STL容器代码重构方案咨询

重构重复代码:消除STL容器操作中的代码异味

你现在碰到的是典型的重复代码问题——三段逻辑里都包含了shirtA.cleanliness = shirtACleanliness、itemsToWash.insert(shirtA)和doSomeOtherStuff(shirtA)这些操作,只是前两段多了各自容器的删除步骤,第三段直接执行公共逻辑。你之前尝试提取执行条件的思路方向是对的,但确实会导致条件表达式冗长,下面给你几种更优雅的重构方案,既不会过度设计,又能让代码更整洁易维护。

方案一:封装公共逻辑为独立函数(最稳妥,无过度设计)

这是最直接的解决方案,把重复的代码抽成一个独立函数就好——这些操作是明确的公共行为,完全适合封装,而且以后要修改逻辑的话,只需要改这一处:

// 假设Shirt是你的衬衫类类型
void updateShirtAndMoveToWash(Shirt& shirt, int newCleanliness, std::set<Shirt>& washSet) {
    shirt.cleanliness = newCleanliness;
    washSet.insert(shirt);
    doSomeOtherStuff(shirt);
}

然后原来的代码就能简化成这样,顺便还把重复的判断条件抽成了needsUpdate变量,可读性更高:

int shirtACleanliness = calculateCleanliness(shirtA);
bool needsUpdate = (shirtA.cleanliness > shirtACleanliness);

if (itemsToWash.contains(shirtA)) {
    if (needsUpdate) {
        itemsToWash.erase(shirtA);
        updateShirtAndMoveToWash(shirtA, shirtACleanliness, itemsToWash);
    }
} else if (itemsToDry.contains(shirtA)) {
    if (needsUpdate) {
        itemsToDry.erase(shirtA);
        updateShirtAndMoveToWash(shirtA, shirtACleanliness, itemsToWash);
    }
} else {
    updateShirtAndMoveToWash(shirtA, shirtACleanliness, itemsToWash);
}

方案二:用Lambda临时封装(适合局部复用,避免命名空间污染)

如果这段公共逻辑只在当前函数里用到,不想单独抽成全局或类成员函数,用Lambda是个绝佳选择——它的好处是逻辑就近,不用跳转到其他地方看实现,也不会污染外部命名空间:

int shirtACleanliness = calculateCleanliness(shirtA);
bool needsUpdate = (shirtA.cleanliness > shirtACleanliness);

// 用Lambda封装局部公共逻辑,捕获需要的变量
auto processShirtForWash = [&](Shirt& shirt) {
    shirt.cleanliness = shirtACleanliness;
    itemsToWash.insert(shirt);
    doSomeOtherStuff(shirt);
};

if (itemsToWash.contains(shirtA)) {
    if (needsUpdate) {
        itemsToWash.erase(shirtA);
        processShirtForWash(shirtA);
    }
} else if (itemsToDry.contains(shirtA)) {
    if (needsUpdate) {
        itemsToDry.erase(shirtA);
        processShirtForWash(shirtA);
    }
} else {
    processShirtForWash(shirtA);
}

方案三:调整条件结构(不推荐,可读性较差)

你之前尝试提取公共执行条件的思路,其实可以换个方式:先处理需要删除的特殊情况,再统一执行公共逻辑,但这个方案的可读性不如前两种,需要读者仔细梳理逻辑,所以不太推荐:

int shirtACleanliness = calculateCleanliness(shirtA);
bool needsUpdate = (shirtA.cleanliness > shirtACleanliness);

// 先处理需要从原容器删除的场景
if (needsUpdate) {
    if (itemsToWash.contains(shirtA)) {
        itemsToWash.erase(shirtA);
    } else if (itemsToDry.contains(shirtA)) {
        itemsToDry.erase(shirtA);
    }
}

// 判断是否需要执行公共操作
bool shouldProcess = false;
if (needsUpdate || (!itemsToWash.contains(shirtA) && !itemsToDry.contains(shirtA))) {
    shouldProcess = true;
}

if (shouldProcess) {
    shirtA.cleanliness = shirtACleanliness;
    itemsToWash.insert(shirtA);
    doSomeOtherStuff(shirtA);
}

怎么选?

  • 如果这段公共逻辑在多个函数/模块里复用,优先选方案一,它清晰、易于维护,是标准的代码复用方式;
  • 如果逻辑只在当前函数内使用,选方案二更合适,保持代码内聚性,避免不必要的函数暴露;
  • 方案三尽量别用,它的条件判断绕,可读性差,反而会增加后续维护成本。

至于你担心的“过度设计”——不管是函数封装还是Lambda,都不属于过度设计,它们都是解决重复代码的常规手段。只要逻辑明确,封装不仅合理,还能降低维护成本(比如以后要修改doSomeOtherStuff的逻辑,只需要改一处就行)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.12 05:10:40