2

所以,正如已经向我指出的(我完全同意),时间耦合是一种设计味道,通常以以下形式出现:

interface IDoSomething
{
    void Initialise();

    void DoSomethingThatOnlyWorksAfterInitialising();
}

在上面的形式中,您可能可以做一些事情(通过构造函数注入或通过抽象工厂等)。

但是,这如何适用于工作单元

我目前正处于我的 UoW 看起来有点像的欢乐混乱中

interface IUnitOfWork
{
    void Initialise(); // sorts out connection sharing/opening/yada

    void Rollback();

    void Commit();
}

诚然,初始化仍然不应该存在。我设法通过Enlist在我的案例中调用该方法来说服自己。忽略这一点,是否考虑 时间耦合下?Rollback Commit


进一步的想法

稍微思考了一下,是不是措辞(“时间耦合”)的选择是错误的,或者至少是我对措辞的解释?

在我看来,这种气味试图做的是让编码人员不要依赖某种形式的方法,这可能是违反直觉的,正如上面链接中的框架示例Initialise所指出的那样。EndpointAddressBuilder

但是,有效终止进一步使用该类的方法是否可以接受?像这样的方法Dispose显然有某种形式的时间耦合;打电话后尝试使用课程会给Dispose你带来问题,你应该知道得更好。Commit与,类似Rollback,我怀疑在其他情况下还有其他各种示例。

气味是否仅与初始化耦合有关(或其中一位博主可以提出的更好的词选择?)。

4

2 回答 2

1

Initialize应该返回一个可以回滚或提交的对象:

interface IUnitOfWorkFactory
{
     IUnitOfWork Create();
}

interface IUnitOfWork : IDisposable
{
    void Commit();
    void Rollback(); // should get called by Dispose if Commit was never called.
}

此外,理想情况下,您IUnitOfWork应该扩展IDisposable,并且Dispose应该与Rollback.

于 2013-04-22T15:19:57.650 回答
1

使用abstract基础和模板模式

一般来说,如果正确的执行顺序是一个问题,请在一个abstract类中实现该顺序。至于IUnitofWork方法使它们virtualabstract(视情况而定)并编写一个固定调用顺序的方法(因此,模板)-并且您不会使基类“实现”接口。此外,abstract基础可以声明任何接口的实现,然后推迟实现或提供默认实现。

于 2013-04-23T14:45:42.267 回答