使用什么设计模式来实现事务或链接机制

2022-09-03 06:22:34

我用C#和Java实现了一个简单的工厂类。此类生成具有一个相同接口的具体工作类的实例。特别是所有这些类都有这样的方法:

create
select
alter
etc.

现在我想有一个机制(建立在一些经典/非经典模式之上),它将允许我创建这些方法的“链”或将它们封装在一种事务中。在伪代码中,我希望看到如下内容:

Transaction tnx = create(...args...).alter(...args_2...);
//tnx.Execute();

或者类似的东西:

Transaction tnx;
tnx.Start();
tnx.Add(method_name, ... variable list of arguments ...);
tnx.Add(another_method_name, ... variable list of arguments ...);
tnx.Execute();

我不擅长设计模式,我不确定要使用什么模式。我希望有人可以分享并删除几行代码(在C#或Java中),以演示如何实现它。谢谢!


答案 1

工作单元是表示域事务的正确模式。

它累积更改(添加,更新和删除),并且可以原子地接受或丢弃它们。原子性由整个工作单元的实现来保证,实现者必须确保以原子方式持久保存或丢弃更改。

看看 Martin Fowler 如何在他的模式目录中定义它:

维护受业务事务影响的对象列表,并协调写出更改和解决并发问题。

工作单元模式的可能接口可以是:

public interface IUnitOfWork
{
     void Commit();
     void Rollback();
}

您还可以将以下方法添加到接口中:

// Note I've added a generic type parameter to define what kind of
// objects will handle the whole unit of work
public interface IUnitOfWork<TObject>
{
     void RegisterNew(TObject some);
     void RegisterUpdated(TObject some);
     void RegisterDeleted(TObject some);
     void Commit();
     void Rollback();
}

无论如何,所有更新都应使用由工作单元监视的更改跟踪进行处理,并且某些添加删除也是如此:

  • 如果将新对象添加到与某个其他对象(1-n 关联)关联的集合中,则工作单元应该能够检测到该对象是脏的,并且应该保留该对象,而无需手动通知工作单元这样做。

  • 删除也是如此。如果从 1-n 关联中删除某个对象,并且没有其他对象引用该对象(孤立对象),则应将其自动标记为已删除

大多数数据映射器(如 OR/M 框架)已经使用对象代理实现对象更改跟踪,以拦截属性集调用。


答案 2

对于对部分-整体系统进行建模的情况,复合模式是一个显而易见的选择。下面是该模式的示意图:

Composite pattern

假设您有一个生产相同接口对象的工厂,那么您几乎完成了复合模式的实现。

  • 您的工厂生产符合某些接口的对象。此接口是复合实现的组件接口。
  • 工厂生成具体类,这些类表示复合实现中的类。Leaf

留给您构建的唯一类是类。Composite

假设您的界面如下所示:Component

public interface IComponent {
    void Create();
    void Alter();
    void Execute();
}

然后,您的复合类可能如下所示:Transaction

public class Transaction : IComponent {
    private readonly IList<IComponent> components = new List<IComponent>();
    public void Add(IComponent c) {
        components.Add(c);
    }
    void Create() {
        foreach (var c in components) {
            c.Create();
        }
    }
    void Alter() {
        foreach (var c in components) {
            c.Alter();
        }
    }
    void Execute() {
        foreach (var c in components) {
            c.Execute();
        }
    }
}

推荐