gpt4 book ai didi

c# - 开始、完成和失败方法中周围代码的设计模式

转载 作者:行者123 更新时间:2023-11-30 14:24:13 25 4
gpt4 key购买 nike

假设我有多个任意代码段要运行,但在每个部分之前,我必须运行一个 Start() 方法,然后在每个部分之后我需要运行一个 Complete( ) 方法。但是,如果在代码部分抛出异常,我想运行 Fail(string message) 方法而不是 Complete()。是否有一种设计模式可以优雅地封装它以使其整洁且易于重复?

例如,假设我有一个名为 Thing 的类型,它包含一个 Start() 方法,该方法将一行添加到日志记录数据库表以反射(reflect)任务是在进行中,一个 Complete() 方法更改该行以反射(reflect)任务已完成,一个 Fail(string message) 方法更改该行以反射(reflect)任务失败.不过,这些只是示例,他们可以执行任何设置和整理类型的任务。

天真的实现可能只是手动调用这些方法:

public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}

但是如果我不得不在很多不同的地方重复这个,它最终会产生很多重复,并且可能很容易忘记调用 Complete 或弄乱它以某种微妙的方式上升。

在 C# 中,有 using 模式,它提供了封装大部分内容的好方法。例如,如果我的 Thing 类型如下所示:

public class Thing : IDisposable
{
public Thing(){
Start();
}

private void Start() { /* start */ }
private void Complete() { /* complete */ }

public void Dispose()
{
Complete();
}
}

我的 DoStuff() 方法现在可以简化为:

public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}

哪个更好。但是如果抛出异常,它不允许我调用 Fail 而不是 Complete 因为(我认为!) Dispose 方法本质上是在 Finally block 中调用。

我想过在 using block 中有一个 try/catch 然后在 中设置一个 thing.HasFailed 标志catch block ,然后在 Dispose 方法中使用它来决定是Complete 还是Fail。但这似乎有点繁琐,我希望 Thing 的消费者必须做尽可能少的事情才能使其正常工作。

那么有没有一种设计模式可以把我想做的事情封装起来,避免每次都手动写一个try\catch呢?

最佳答案

你可以有这样一个Thing:

public class Thing 
{
private void Start() { /* start */ }
private void Complete() { /* complete */ }
private void Fail(string message) {}

public void DoAction(Action action)
{
this.Start();
try
{
action();
this.Complete();
}
catch (Exception e)
{
this.Fail(e.Message);
}

}
}

然后像这样使用它:

Thing thing = new Thing();
thing.DoAction(this.DoStuff);

关于c# - 开始、完成和失败方法中周围代码的设计模式,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41850274/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com