1

有时当我使用一个类(我们称之为它MyClass)时,我需要在本地更改它的行为并确保之后恢复默认行为。

我正在考虑创建另一个类(例如MyClassBehaviorSwitcher)实现IDisposable. 在构造函数中,它将设置一些静态属性并在Dispose()方法中取消设置。MyClass然后将考虑静态属性的值。使用示例:

using (new MyClassBehaviorSwitcher()) {
    // Work with MyClass, which will behave differently
    // until the end of the block.
}

这样,我确保之后恢复默认行为。即使客户端代码不使用using,该对象也会在某个时候被释放。

我的问题:这是一种模式吗?这些类有命名约定吗?或者也许我忽略了一些东西,并且有更好的方法来实现我想要的?

4

2 回答 2

2

是的,它是一种模式,虽然我不知道它是否有一个特定的名称。我称之为“范围”模式。

例如,System.Transactions使用此模式。Transaction.Current是线程静态“环境”事务,TransactionScope在处理时提交或回滚该事务。

于 2013-09-25T09:54:48.520 回答
1

您描述的是一种常见的范围行为模式。然而,它有一个显着的弱点,即方法中的代码Dispose无法知道它是因为using块内发生异常而被调用,还是因为非异常退出而被调用。using在代码需要根据是否发生异常采取不同操作的情况下,该模式不可用。更糟糕的是,使用该using模式与可以区分“异常”和“非异常”情况的模式之间在便利性方面的相对差异意味着许多应该区分这些情况的代码没有。

除此之外,如果事务范围的语义要求在代码离开范围之前必须提交或回滚任何开始的异常,如果尝试离开范围而不执行提交或回滚可能会触发,这将很有帮助一个例外。不幸的是,如果作用域块无法确定是否由于异常而离开了作用域,它通常必须在三个丑陋的替代方案中进行选择:

  • 静默执行回滚,因此如果代码在没有提交或回滚事务的情况下非异常退出,则不会提供不正确使用的指示。

  • 抛出异常,从而覆盖任何可能已挂起的异常。

  • 包含记录不当使用的代码,从而引入对所使用的任何日志记录方法的依赖。

如果没有一个未决的或抛出一个异常但将任何未决的异常包装在其中,则范围偏离会引发异常,这将比上述任何一种替代方案更干净,但除非使用相当笨重的 try/finally,否则这是不可能的图案。

于 2013-09-25T17:35:27.320 回答