我有一个大对象,在我用它做某事之前,我需要检查多个条件。我有一个很大的功能。这是不可读的,我想把它拆分为较小的功能,使我的代码更清晰。
该函数正在检查条件,如果某些内容不正确,它会停止并返回问题(属于enum
类型)。
看起来像这样:
AnswerEnum CheckEverything(Bigobj o)
{
// some calculation
if (...)
return AnswerEnum.Error1;
// some more calculation
if (...)
return AnswerEnum.Error2;
...
return AnswerEnum.OK;
}
现在,我想在较小的函数中进行计算,我可以做到以下几点:
AnswerEnum CheckEverything(Bigobj o)
{
AnswerEnum ret;
ret=CheckFirstThing(o);
if (ret!=AnswerEnum.OK)
return ret;
ret=CheckSecondThing(o);
if (ret!=AnswerEnum.OK)
return ret;
...
return AnswerEnum.OK;
}
此解决方案包含
if (ret!=AnswerEnum.OK)
return ret;
多次,我不喜欢它。
我想最小化return
语句的数量和代码的任何重复部分。在这种情况下我该怎么做?
答案 0 :(得分:6)
如果您的所有检查功能都具有相同的签名(在您发布的代码中似乎就是这种情况),那么您所要做的就是创建一个代表列表,如下所示:
List<Func<Bigobj, AnswerEnum>> list;
然后在类初始化期间将所有检查方法添加到其中:
list.Add(CheckFirstThing);
list.Add(CheckSecondThing);
最后,检查一切:
AnswerEnum ret;
foreach(Func<Bigobj, AnswerEnum> f in list)
{
ret = f(o);
if (ret != AnswerEnum.Ok) return ret;
}
return AnswerEnum.Ok;
答案 1 :(得分:4)
定义一个新方法:
private AnswerEnum ConditionalCheck(AnswerEnum current,
Func<BigObj, AnswerEnum> func,
BigObj obj)
{
return current == AnswerEnum.OK ? func(obj) : current;
}
然后将您的代码修改为:
AnswerEnum CheckEverything(Bigobj o)
{
var ret = AnswerEnum.OK;
ret = ConditionalCheck(ret, CheckFirstThing, o);
ret = ConditionalCheck(ret, CheckSDecondThing, o);
return ret;
}
或者,如果您真的想减小方法的大小,我会将其更改为:
AnswerEnum CheckEverything(List<Func<BigObj, AnswerEnum> funcs, Bigobj o)
{
foreach (var func in funcs)
{
var result = func(o);
if (result != AnswerEnum.OK) { return result; }
}
return AnswerEnum.OK;
}
这样您就可以注入一组检查,因此更容易阅读,测试和维护。此外,一旦出现故障就检查中止,使其更快。
答案 2 :(得分:0)
恕我直言,如果要进行多次检查,使用Delegate Dictionary Design Pattern
(http://wilbloodworth.com/delegate-dictionary-pattern/)会更好:
AnswerEnum CheckEverything(Bigobj o)
{
List<Func<AnswerEnum>> checkings = new List<Func<AnswerEnum>>
{
(obj)=>{return CheckFirstThing(obj);},
(obj)=>{return CheckSecondThing(obj);}
};
foreach(var chk in checkings)
{
AnswerEnum answer;
if((answer= chk(o))!=AnswerEnum.OK)
return answer;
}
return AnswerEnum.OK;
}