所以,正如pointed out to me(我完全同意),temporal coupling是一种设计气味,通常以下列形式出现:
interface IDoSomething
{
void Initialise();
void DoSomethingThatOnlyWorksAfterInitialising();
}
在上面的表格中,你可以做些什么(通过构造函数注入或者通过抽象工厂等)。
然而,这如何适用于工作单位?
我目前正处于我的UoW看起来有点像
的快乐混乱中interface IUnitOfWork
{
void Initialise(); // sorts out connection sharing/opening/yada
void Rollback();
void Commit();
}
不可否认,初始化仍然不应该存在。在我的案例中,我设法通过调用方法Enlist
来说服自己。忽略这一点,是 Rollback
和 Commit
在时间耦合下考虑? < / p>
稍微考虑一下,是不是选择措辞(“时间耦合”)是错误的,或者至少是我对措辞的解释?
在我看来,气味试图做的是让编码人员不依赖某种形式的Initialise
方法,这可能与EndpointAddressBuilder
框架示例所指出的一样反直觉。在上面的链接上。
但是,有效终止课程进一步使用的方法是可以接受的吗?像Dispose
这样的方法显然有某种形式的时间耦合;在调用Dispose
之后尝试使用该类会导致问题,你应该知道更好。与Commit
,Rollback
类似,在其他情况下,我怀疑其他各种示例。
气味只与初始化耦合有关(或者其中一个博主可以提出哪些更好的词语选择?)。
答案 0 :(得分: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
相同。
答案 1 :(得分:1)
使用abstract
基础和模板模式
通常,如果正确的执行顺序是abstract
类中的顺序的关注实现。对于IUnitofWork
方法,使它们virtual
或abstract
(视情况而定)并编写一个修复调用顺序的方法(因此,模板) - 并且你不做基础类“实现”接口。此外,abstract
base可以声明任何接口的实现,然后推迟实现或提供默认实现。