用于实现事务或链接机制的设计模式

时间:2015-11-08 12:09:26

标签: java c# design-patterns

我在C#和Java中实现了一个简单的Factory类。此类构建具有同一个接口的具体工作类的实例。特别是所有这些类都有如下方法:

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中),这些代码将演示如何实现它。谢谢!

2 个答案:

答案 0 :(得分:7)

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

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

检查Martin Fowler如何定义它on his pattern catalog

  

维护受业务事务影响的对象列表   协调写作的变化和分辨率   并发问题。

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

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框架)已使用对象代理实现对象更改跟踪以拦截属性集调用。

答案 1 :(得分:4)

Composite pattern是您为整体系统建模时的明显选择。以下是模式图表的外观:

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();
        }
    }
}