[英]Best design pattern for structured sequential handling
Doing maintenance on a project I came across code, which I find unnecessary hard to read and I wish to refactor, to improve readability. 对项目进行维护我遇到了代码,我觉得这些代码难以阅读,我希望重构,以提高可读性。
The functionality is a long chain of actions that need to be performed sequentially. 功能是需要按顺序执行的长链操作。 The next action should only be handled if the previous action was successful.
只有在上一个操作成功时才应处理下一个操作。 If an action is not successful a corresponding message needs to be set.
如果操作不成功,则需要设置相应的消息。 And the returned type is a Boolean.
返回的类型是布尔值。 (successful true/false).
(成功的真/假)。 Just like the return type of all the called actions.
就像所有被调用动作的返回类型一样。
Basically it comes down to something like this. 基本上它归结为这样的事情。
string m = String.Empty; // This is the (error)Message.
bool x = true; // By default the result is succesful.
x = a1();
if(x) {
x = a2();
}
else {
m = "message of failure a1";
return x;
}
if(x) {
x = a3();
}
else {
m = "message of failure a2";
return x;
}
//etcetera..etcetera...
if(x){
m = "Success...";
}
else{
m = "Failure...";
}
return x;
My question is: What is a better structure / pattern to handle this kind of logic? 我的问题是: 处理这种逻辑的更好的结构/模式是什么?
Main goals are: 主要目标是:
Please keep in mind that it is quite a large chain of actions that is being performed sequentially. 请记住,这是一个相当大的行动链,正在顺序执行。 (Thousands lines of code)
(千行代码)
Make a list of action/message pairs: 列出操作/消息对:
class Activity {
public Func<bool> Action { get; set; }
public String FailureMessage { get; set; }
}
Activity[] actionChain = new[] {
new Activity { Action = A1, FaulureMessage = "a1 failed"}
, new Activity { Action = A2, FaulureMessage = "a2 failed"}
, new Activity { Action = A3, FaulureMessage = "a3 failed"}
};
A1
.. A3
are no-argument methods returning bool
. A1
.. A3
是返回bool
无争论方法。 If some of your actions take parameters, you can use lambda expressions for them: 如果您的某些操作采用参数,则可以使用lambda表达式:
Activity[] actionChain = new[] {
...
, new Activity { Action = () => An(arg1, arg2), FaulureMessage = "aN failed"}
, ...
};
Now you can go through the pairs, and stop at the first failure: 现在你可以通过对,并在第一次失败时停止:
foreach (var a in actionChain) {
if (!a.Action()) {
m = a.FailureMessage;
return false;
}
}
m = "Success";
return true;
@dasblinkenlight was faster... however a similar solution using yield instead of an array: @dasblinkenlight更快......但是使用yield而不是数组的类似解决方案:
public string Evaluate()
{
foreach (var customAction in EnumerateActions())
{
if (!customAction.Execute())
return customAction.Error;
}
return "Success...";
}
public IEnumerable<CustomAction> EnumerateActions()
{
yield return new CustomAction(a1, "Error for A1");
yield return new CustomAction(a2, "Error for A2");
...
}
public class CustomAction
{
public Func<bool> Execute { get; }
public string Error { get; }
public CustomAction(Func<bool> action, string error)
{
Execute = action;
Error = error;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.