【问题标题】:What Design Pattern to use to implement transaction or chaining mechanism使用什么设计模式来实现事务或链接机制
【发布时间】:2015-11-08 12:09:26
【问题描述】:

我用 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 中),它们将演示如何实现这一点。谢谢!

【问题讨论】:

    标签: java c# design-patterns


    【解决方案1】:

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

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

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

    无论如何,所有更新都应该使用由工作单元监控的更改跟踪来处理,并且还有一些添加删除

      1234563这样做的工作单元。
    • 对于删除也是如此。如果您从 1-n 关联中删除一个对象并且没有其他对象引用它(一个孤立对象),它应该被自动标记为已删除

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

    【讨论】:

    • 谢谢!听起来很有用!我会检查并测试这个模式。
    • @Jacobian 复合模式反正和你想解决什么没关系!
    • 我猜,你是对的。看来您的建议更适合这项任务。
    • @Jacobian 我想是的;P
    【解决方案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();
            }
        }
    }
    

    【讨论】:

    • 感谢这个伟大的杰作!我很喜欢!但是我可以请你用几行代码来演示它是如何使用的。我问这个,因为在我看来,事务类与具体类的关系太密切了。不应该更解耦吗?顺便说一句,您如何看待命令模式?它不是比复合模式更适合任务吗?
    • @Jacobian Transaction 类实现与具体类相同的IComponent 接口的目的是您可以将Transaction 添加为另一个事务的成员,该事务本身可能包括其他事务。 Command 模式隐藏了整体与部分的区别,但组合不是它的一部分。
    • @Jacobian 我也强烈不同意 Matías 的无条件评论,即“复合模式与您想要解决的问题无关”,因为您在描述自己时所说的“交易”实现与原子一致持久隔离意义上的事务几乎没有关系。您正在制作的内容看起来像是一组动作,而复合模式在实现这一点的方式上提供了很大的灵活性。
    • 我不确定,什么最适合我。可能,你们都是对的,它只取决于在工人阶级中实施的上下文和具体任务。谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2010-09-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多