编码模式c#
前几天,我在一次代码审查中遇到了一些类似的代码编码模式c#,c#,refactoring,C#,Refactoring,前几天,我在一次代码审查中遇到了一些类似的代码 public void DoSomeTasks() { if (CheckSomeState()==true) return; DoTaskOne(); if (CheckSomeState()==true) return; DoTaskTwo(); if (CheckSomeState()==true) return; DoTaskThree(); if (CheckSomeState()==true) r
public void DoSomeTasks()
{
if (CheckSomeState()==true) return;
DoTaskOne();
if (CheckSomeState()==true) return;
DoTaskTwo();
if (CheckSomeState()==true) return;
DoTaskThree();
if (CheckSomeState()==true) return;
DoTaskFour();
}
随着任务数量的增加,代码的圈复杂度越来越高,我觉得这也不对
我提出的解决方案是
private void DoTasksWhile(Func<bool> condition, Action[] tasks)
{
foreach (var task in tasks)
{
if (condition.Invoke()==false) break;
task.Invoke();
}
}
有人对如何提高代码的可读性提出了建议吗?如果您的编排代码非常复杂,请考虑使用WF(workflow foundation)等框架 否则,您的代码很好,但我不会更改初始代码,因为它更具可读性。它也更加灵活,因为将来您可能会修改这些IFs,即条件可能不会保持相同
我看不出圈复杂度是如何降低的,或者可以如何降低。我对您的实现进行了一些重构
private void DoTasksWhile(Func<bool> predicate, IEnumerable<Action> tasks)
{
foreach (var task in tasks)
{
if (!predicate())
return;
task();
}
}
用法将非常简单:
tasks.DoWhile(() => CheckSomeState());
您的解决方案就目前而言是完全足够的(尽管在仅四个步骤的情况下可能会有过大的杀伤力),但在这种情况下,它是否是最佳方法取决于CheckSomeState在您的程序上下文中的实际用途:
- 在每个任务之间只调用一次CheckSomeState是否重要李>
- 有时也需要在任务的中途调用它吗
CheckForCancel();
DoTaskOne();
CheckForCancel();
DoTaskTwo();
(下边是一些人会认为这是使用异常控制流,这通常是皱眉)。< / P>
我还应该补充一点,目标不应该是减少圈复杂度,而是要有易于理解和维护的代码。圈复杂度是一个有用的指标,但有时它会不必要地惩罚非常简单的代码。解决什么问题?你似乎已经准备好了干溶液。可读性问题到底是什么?您经常需要将布尔值与
true/false
进行比较。只需在if
语句条件中使用布尔值。哇,缩进模式非常混乱……这是打开的。@Oded,谢谢,当我发布时,我意识到原来的代码不是干的这一事实是困扰我的。我在想也许有一种方法可以更流畅地实现这一点。e、 g.While(someCondition).Do(firstTask()).ThenDo(secondTask).ThenDo(thirdTask).Go(0);谢谢,==true更易于描述,它清楚地表明代码返回的是布尔值,但是if语句也暗示了这一点。删除调用()使代码更整洁。@安得烈考虑重命名<代码> CuthSoMalds<代码>方法,以显示它返回布尔值,例如“代码> ISSOMOSWANDS >代码> @安得烈:只有对布尔值进行求值的表达式才能出现在<代码>内,如果语句,则不必明确说明。至于意外分配而不是比较。。。不太可能。编译器将警告您条件表达式中的赋值。
tasks.DoWhile(() => CheckSomeState());
CheckForCancel();
DoTaskOne();
CheckForCancel();
DoTaskTwo();