Tim*_*lay 3 c# design-patterns
假设我有各种各样的代码段要运行,但在每个部分之前,我必须运行一个Start()方法,然后在每个部分后我需要运行一个Complete()方法.但是,如果在代码部分抛出异常,我想运行一个Fail(string message)方法而不是Complete().是否有一种优雅的封装设计模式,使其整洁,易于重复?
例如,假设我有一个名为的类型Thing,其中包含一个Start()方法,该方法将一行添加到日志记录db表以反映任务正在进行中,该Complete()方法更改该行以反映任务已完成以及Fail(string message)更改方法的方法行反映任务失败.这些只是一些例子,他们可以做任何设置和整理类型的任务.
天真的实现可能只是手动调用这些方法:
public void DoStuff()
{
var thing = new Thing();
thing.Start();
try
{
DoImportantStuff();
thing.Complete();
}
catch (Exception e)
{
thing.Fail(e.Message);
}
}
Run Code Online (Sandbox Code Playgroud)
但是如果我不得不在很多不同的地方重复这一点,它最终会造成很多重复,并且可能很容易忘记以Complete某种微妙的方式打电话或弄乱它.
在C#中,有这种using模式,它提供了封装大部分内容的好方法.例如,如果我的Thing类型如下所示:
public class Thing : IDisposable
{
public Thing(){
Start();
}
private void Start() { /* start */ }
private void Complete() { /* complete */ }
public void Dispose()
{
Complete();
}
}
Run Code Online (Sandbox Code Playgroud)
我的DoStuff()方法现在可以简化为:
public void DoStuff()
{
using(new Thing())
{
DoImportantStuff();
}
}
Run Code Online (Sandbox Code Playgroud)
哪个更好.但它不允许我调用Fail而不是Complete抛出异常,因为(我认为!)该Dispose方法基本上是在一个Finally块中调用的.
我想到了一个块try/catch内部using,然后在块内设置一个thing.HasFailed标志catch,然后在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);
}
}
}
Run Code Online (Sandbox Code Playgroud)
并像这样使用它:
Thing thing = new Thing();
thing.DoAction(this.DoStuff);
Run Code Online (Sandbox Code Playgroud)