含重复逻辑的条件语句与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
相关产品推荐
相关产品推荐

