Looking over the definition of the Unit of Work pattern it seems very much like what a programmer would get if they implemented a Monad such as an IO or Transaction Monad. What makes the unit of work concept fundamentally different from the use of a Monad? Assume that we are working in a language that has enough power to implement most common Monads fully and can implement a unit of work pattern similar to what you may find in Java or C#, especially one with a type system such as Scala's or Haskell's.

If one can be chosen over the other what are the pros and cons of each approach?

  • They have two different purposes. – Robert Harvey Mar 14 '15 at 7:01
  • 2
    UoW : "Maintains a list of objects affected by a business transaction and coordinates the writing out of changes and the resolution of concurrency problems." Monad: "In functional programming, a monad is a structure that represents computations defined as sequences of steps: a type with a monad structure defines what it means to chain operations, or nest functions of that type together." I don't see how they are even similar. – Euphoric Mar 14 '15 at 8:04
  • recommended reading: What is the problem with “Pros and Cons”? – gnat Mar 14 '15 at 12:22
  • @Euphoric well look at the definitions a monad describes a sequence of steps which could be objects or more specifically methods on objects, the unit of work maintains a list of objects (Practically this is really the execution context.) and coordinates writing to the database. A unit of work implementation is free to define how and in what order information is written to a database. How is this substantively different from a kind of IO type that a function returns that defines rollback and commit operations and returns some value? – Kevin Mar 15 '15 at 22:22

Your question is a little odd, sort of like asking why you need the unit of work pattern when you could just use objects. Monads are more fundamental than your question implies. You can use a monad as part of the implementation of the unit of work pattern, but that's not a sufficient description of the solution. You would also need to describe which monad to use, the type parameters used, how to initialize it, how to implement a step, and what to do with the result.

A transaction monad indeed looks like it might be a relatively good building block to implement this pattern, but perhaps a new monad specifically created and tailored for implementing unit of work would be cleaner.

However, part of the benefit of the unit of work pattern is that it helps gather database updates from scattered places in your code. Monads have the annoying property that they want to be already gathered. If you have to gather your database update code into one place anyway, there might be a simpler way to aggregate it.

| improve this answer | |
  • Ok this makes alot of sense. But isn't the unit of work pattern ultimately just a list of functions that mutate a set A with one or more functions? I.E. isn't it a specific case of the pipeline pattern? The Transaction monad serving as the safe place to actually run the specified operations as it would provide the vocabulary that handles committing and rolling back operations. Perhaps returning some type that indicates success or failure. – Kevin Mar 15 '15 at 8:13
  • I'm not saying using a monad is the worst idea, just that there may be a better one. You're presuming you have a list of functions already gathered that do database updates and pretty much only database updates. If you've already met that precondition, you've already solved most of the problem unit of work is intended to solve. At that point there are probably more direct ways available to you of actually performing the updates. – Karl Bielefeldt Mar 15 '15 at 14:02
  • I guess I have just never encountered a situation where I did not already have a collection of mutating operations to work with. The only time I have encountered that is when dealing with dynamic search mechanisms where I needed to add a bunch of expressions together to produce an expression that I could pass to a where clause. But even then that was really just a case of choosing known functions from a larger set. – Kevin Mar 15 '15 at 17:48

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.