Loading ...
Sorry, an error occurred while loading the content.

Repository and UnitOfWork

Expand Messages
  • Stefan_Kluehspies
    Hello All, first I want to say that the ideas and concepts in Eric s book help me very much in thinking about the domain I am working in. I have started a
    Message 1 of 9 , Nov 13, 2003
    • 0 Attachment
      Hello All,
      first I want to say that the ideas and concepts in Eric's book help
      me very much in thinking about the domain I am working in.
      I have started a small project, but I have some difficulties in
      implementing Eric's ideas. I'm using C++, and I could not find many
      examples in this language. So I'm asking if someone with more
      experience could give me some thoughts...

      How do I combine the repository in the domain layer with a
      persistence mechansim? Let me explain this with an example:

      I have an entity in the domain layer, say currency:
      class currency {...};

      Because an entity has identity, I encapsulate this class in a smart
      pointer, so that the services work just with that pointer:
      typedef smart_ptr<currency> currency_ptr;

      So this is the only type I add/get in the repository:
      void currency_repository.add(currency_ptr);
      currency_ptr currency_repository.get(string iso_code);

      My first thought was to encapsulate all persistence mechanism in the
      repository. But Eric states, that the user should decide when to
      commit. So this could be in the repository (like repo.commit()), but
      then I am mixing the two concepts. The bigger problem is, when
      someone changes the object (e.g. currency_ptr->set_name("xy")) the
      repository is unaware of this, and nobody but the user knows, that
      this object should be saved in the database.

      So my next idea was to use Fowler's UnitOfWork (and datamapper etc).
      Besides that I don't know how to implement this in c++ (I could only
      find java examples), I have to give the repository a reference to
      this UnitOfWork, which I don't think is a good solution:
      repo.add(uow&, currency_ptr);
      otherwise, I would have to do double work:
      repo.add(currency_ptr ptr);
      uow.registerNew(currency_ptr ptr);?

      Has anybody with more experience solved this kind of problem? Or any
      hint to some c++ code that I could study?
      Thank you,
      Stefan
    • Stafford, Randy
      What if UnitOfWork.commit() caused all newly-registered objects to be added to the appropriate Repository (in an ACID way)? I can t give an example in C++,
      Message 2 of 9 , Nov 13, 2003
      • 0 Attachment
        What if UnitOfWork.commit() caused all newly-registered objects to be added to the appropriate Repository (in an ACID way)? I can't give an example in C++, but I could probably conjure one in Java, assuming a way to get the appropriate Repository for a (type of) domain object. The harder part is the ACID semantics. Assuming O/R mapping, Repository add() methods would have to execute insert statements against an RDBMS connection that was finally committed by the UnitOfWork.

        Randy

        > -----Original Message-----
        > From: Stefan_Kluehspies [mailto:stefan.kluehspies@...]
        > Sent: Thursday, November 13, 2003 10:10 AM
        > To: domaindrivendesign@yahoogroups.com
        > Subject: [domaindrivendesign] Repository and UnitOfWork
        >
        >
        > Hello All,
        > first I want to say that the ideas and concepts in Eric's book help
        > me very much in thinking about the domain I am working in.
        > I have started a small project, but I have some difficulties in
        > implementing Eric's ideas. I'm using C++, and I could not find many
        > examples in this language. So I'm asking if someone with more
        > experience could give me some thoughts...
        >
        > How do I combine the repository in the domain layer with a
        > persistence mechansim? Let me explain this with an example:
        >
        > I have an entity in the domain layer, say currency:
        > class currency {...};
        >
        > Because an entity has identity, I encapsulate this class in a smart
        > pointer, so that the services work just with that pointer:
        > typedef smart_ptr<currency> currency_ptr;
        >
        > So this is the only type I add/get in the repository:
        > void currency_repository.add(currency_ptr);
        > currency_ptr currency_repository.get(string iso_code);
        >
        > My first thought was to encapsulate all persistence mechanism in the
        > repository. But Eric states, that the user should decide when to
        > commit. So this could be in the repository (like repo.commit()), but
        > then I am mixing the two concepts. The bigger problem is, when
        > someone changes the object (e.g. currency_ptr->set_name("xy")) the
        > repository is unaware of this, and nobody but the user knows, that
        > this object should be saved in the database.
        >
        > So my next idea was to use Fowler's UnitOfWork (and datamapper etc).
        > Besides that I don't know how to implement this in c++ (I could only
        > find java examples), I have to give the repository a reference to
        > this UnitOfWork, which I don't think is a good solution:
        > repo.add(uow&, currency_ptr);
        > otherwise, I would have to do double work:
        > repo.add(currency_ptr ptr);
        > uow.registerNew(currency_ptr ptr);?
        >
        > Has anybody with more experience solved this kind of problem? Or any
        > hint to some c++ code that I could study?
        > Thank you,
        > Stefan
        >
        >
        >
        > ------------------------ Yahoo! Groups Sponsor
        > ---------------------~-->
        > Buy Ink Cartridges or Refill Kits for your HP, Epson, Canon or Lexmark
        > Printer at MyInks.com. Free s/h on orders $50 or more to the
        > US & Canada.
        > http://www.c1tracking.com/l.asp?cid=5511
        > http://us.click.yahoo.com/mOAaAA/3exGAA/qnsNAA/NhFolB/TM
        > --------------------------------------------------------------
        > -------~->
        >
        > To unsubscribe from this group, send an email to:
        > domaindrivendesign-unsubscribe@yahoogroups.com
        >
        >
        >
        > Your use of Yahoo! Groups is subject to
        http://docs.yahoo.com/info/terms/
      • Stefan_Kluehspies
        You mean something like UnitOfWork.registerNew(currency_ptr ptr) { (find currency_repository); repo.add(ptr); my_new_objects.add(ptr); } and then in the client
        Message 3 of 9 , Nov 14, 2003
        • 0 Attachment
          You mean something like
          UnitOfWork.registerNew(currency_ptr ptr) {
          (find currency_repository);
          repo.add(ptr);
          my_new_objects.add(ptr);
          }

          and then in the client code just
          uow.registerNew(currency_ptr ptr);
          uow.commit();??

          I haven't thought of that until now. I will give it a try.
          Thank you very much, Randy,
          Stefan

          --- In domaindrivendesign@yahoogroups.com, "Stafford, Randy"
          <rstafford@i...> wrote:
          > What if UnitOfWork.commit() caused all newly-registered objects to
          be added to the appropriate Repository (in an ACID way)? I can't
          give an example in C++, but I could probably conjure one in Java,
          assuming a way to get the appropriate Repository for a (type of)
          domain object. The harder part is the ACID semantics. Assuming O/R
          mapping, Repository add() methods would have to execute insert
          statements against an RDBMS connection that was finally committed by
          the UnitOfWork.
          >
          > Randy
          >
        • Logan, Patrick D
          ... My general approach is to define objects at the domain level that do what the customer wants. So for example if the customer wants to build a purchase
          Message 4 of 9 , Nov 14, 2003
          • 0 Attachment
            > My first thought was to encapsulate all persistence mechanism in the
            > repository. But Eric states, that the user should decide when to
            > commit. So this could be in the repository (like repo.commit()), but
            > then I am mixing the two concepts. The bigger problem is, when
            > someone changes the object (e.g. currency_ptr->set_name("xy")) the
            > repository is unaware of this, and nobody but the user knows, that
            > this object should be saved in the database.

            My general approach is to define objects at the domain level that do
            what the customer wants. So for example if the customer wants to build
            a purchase order, send it around for approvals and modifications, and
            then submit that, then build a purchase order object and the objects
            you need for updating it, approving it, etc. in the customer's
            language.

            On the user interface side, use these abstractions with this
            language. The user's experience of the application can then be tested
            without an understanding of what repositories, databases, and
            transactions are involved "in the back office".

            On the backside of the application, create subclasses of these
            customer abstractions as needed, e.g. FlatFilePurchaseOrder,
            CachedPurchaseOrder, DatabasedPurchaseOrder. (Two or more of these
            might be used in conjunction on a complete system.) The key is too hide
            all this stuff the customer really doesn't care about (and that might
            change independent of changes to the business processes.)

            It's here on the backside of the abstracted customer language that the
            acts of updating, approving, and submitting are translated into
            transactions. i.e. there may be multiple kinds of transactions saving
            the objects in various forms up to and including saving the final
            purchase order in some system like SAP R3, et al.

            Two small examples...

            someCachedPurchaseOrder.approve(someManager);

            This might update the cached objects and tell the database'd objects
            to save themselves. (e.g. the database may be an "operational data
            store" for work in progress, ultimately headed for SAP R3.)

            someCachedPurchaseOrder.submit();

            This might update the cached object, tell the database'd objects to
            save themselves, and tell the file-based objects to format themselves
            into a purchase order and ftp themselves to the SAP landing zone.

            -Patrick
          • Chris Gardner
            ... the ... but ... the ... that ... do ... build ... and ... objects ... tested ... hide ... might ... Is the storage medium (flat file, cached, database) a
            Message 5 of 9 , Nov 14, 2003
            • 0 Attachment
              --- In domaindrivendesign@yahoogroups.com, "Logan, Patrick D"
              <patrick.d.logan@i...> wrote:
              > > My first thought was to encapsulate all persistence mechanism in
              the
              > > repository. But Eric states, that the user should decide when to
              > > commit. So this could be in the repository (like repo.commit()),
              but
              > > then I am mixing the two concepts. The bigger problem is, when
              > > someone changes the object (e.g. currency_ptr->set_name("xy"))
              the
              > > repository is unaware of this, and nobody but the user knows,
              that
              > > this object should be saved in the database.
              >
              > My general approach is to define objects at the domain level that
              do
              > what the customer wants. So for example if the customer wants to
              build
              > a purchase order, send it around for approvals and modifications,
              and
              > then submit that, then build a purchase order object and the
              objects
              > you need for updating it, approving it, etc. in the customer's
              > language.
              >
              > On the user interface side, use these abstractions with this
              > language. The user's experience of the application can then be
              tested
              > without an understanding of what repositories, databases, and
              > transactions are involved "in the back office".
              >
              > On the backside of the application, create subclasses of these
              > customer abstractions as needed, e.g. FlatFilePurchaseOrder,
              > CachedPurchaseOrder, DatabasedPurchaseOrder. (Two or more of these
              > might be used in conjunction on a complete system.) The key is too
              hide
              > all this stuff the customer really doesn't care about (and that
              might
              > change independent of changes to the business processes.)

              Is the storage medium (flat file, cached, database) a proper
              discriminator for subclassing? What if you need to subclass based
              on a business reason, rather than a technical one? You might be
              challenged to come up with storage medium versions of those new
              business subclasses, as well. Hence, you will be discriminating on
              the inheritance hierarchy in two ways: storage approach and
              business specialization. You might have to use design patterns to
              solve that problem.

              The cool thing about repositories is that they can help to abstract
              the actual storage medium. Also, depending on your programming
              language, you may have tools to help you in storage (in conjunction
              with the repository). As discussed previously, JDO and Hibernate
              are two such tools in the Java world.

              >
              > It's here on the backside of the abstracted customer language that
              the
              > acts of updating, approving, and submitting are translated into
              > transactions. i.e. there may be multiple kinds of transactions
              saving
              > the objects in various forms up to and including saving the final
              > purchase order in some system like SAP R3, et al.
              >
              > Two small examples...
              >
              > someCachedPurchaseOrder.approve(someManager);
              >
              > This might update the cached objects and tell the database'd
              objects
              > to save themselves. (e.g. the database may be an "operational data
              > store" for work in progress, ultimately headed for SAP R3.)
              >
              > someCachedPurchaseOrder.submit();
              >
              > This might update the cached object, tell the database'd objects to
              > save themselves, and tell the file-based objects to format
              themselves
              > into a purchase order and ftp themselves to the SAP landing zone.
              >
              > -Patrick
            • Logan, Patrick D
              ... No, I wouldn t make this a subclass relationship. Instead, this would be a compositional relationship. For example the cached object would be composed of
              Message 6 of 9 , Nov 17, 2003
              • 0 Attachment
                > Is the storage medium (flat file, cached, database) a proper
                > discriminator for subclassing? What if you need to subclass based
                > on a business reason, rather than a technical one?

                No, I wouldn't make this a subclass relationship. Instead, this would
                be a compositional relationship. For example the cached object would
                be composed of the objects for domain rules and computations. It would
                also be composed of the external objects with their own
                responsibilities for making the cache ACID, communicating with
                enterprise sources/sinks for the object, etc.

                All the "purchase order" objects would know how to speak purchase
                orders with each other, but only the cached object knows about caches,
                only the SAP object knows about that system and formats, etc.

                I would recommend implementing a domain design to get that fairly
                settled before integrating all the components.

                > The cool thing about repositories is that they can help to abstract
                > the actual storage medium.

                All the same technologies can be used but the compositional approach
                just provides the abstractions for where to isolate the details.

                > Also, depending on your programming language, you may have tools to
                > help you in storage (in conjunction with the repository). As
                > discussed previously, JDO and Hibernate are two such tools in the
                > Java world.

                I don't know much about these two in particular, but even in a nearly
                100% transparent system like Gemstone, there is a benefit to making
                the technology aspects isolated within the domain-driven
                activities. For example, some of the "Gemstone commits" would be used
                to commit work-in-progress. These WIP objects would be isolated from
                enterprise objects via the explicit domain-driven relationships. Only
                when the domain calls for making something known to the enterprise
                would you tie that "Gemstone commit" into an enterprise object. This
                benefits from being captured and represented at the domain level, and
                only underneath somewhere is the object doing a Gemstone commit.

                Hoping this makes some sense in a 5 min. sketch.

                -Patrick
              • Eric Evans
                I thought I d jot down my impressions of ideas and trends that I noticed at OOPSLA and that seem relevant to domain-driven design. This is by no means a
                Message 7 of 9 , Nov 24, 2003
                • 0 Attachment
                  I thought I'd jot down my impressions of ideas and trends that I noticed at
                  OOPSLA and that seem relevant to domain-driven design. This is by no means a
                  balanced assessment of the conference. This is OOPSLA through my eyes.

                  Most striking was the amount of activity around domain modeling and design
                  this year, much more than in earlier years. Partly this may have been
                  emphasized by the track, but I think more people are becoming aware that our
                  biggest challenges lie in that area.

                  Within this general interest in domain design, two particular techniques got
                  a lot of attention, "model-driven architecture" and "domain-specific
                  languages".


                  Model-driven architecture (MDA)
                  -------------------------------
                  I'll tell you right up front; I'm not a believer in this approach. Most of
                  what comes under this name consists of describing part of the system in UML
                  and then generating program code. Attempts to shield us from code amount to
                  forcing us to program in a much more restrictive programming language (e.g.
                  UML). While this can be useful for some subset of applications, I think it
                  is a dead end.

                  As most of you know by now, I believe in building up the domain language
                  based on a model and bringing that language and model to life in code. A
                  programming language that made model expression easier would be most
                  welcome, but UML is not that language.

                  There was a lot of discussion about this at OOPSLA by many enthusiasts and
                  many skeptics. One of the high-points of the conference was a surprising
                  panel discussion on this topic, surprising because it cut to the deep issues
                  and because the participants did not mince words. I greatly enjoyed the
                  comments of Dave Thomas (the lead skeptical panelist) partly because I
                  agreed with him. But one pro-MDA panelist, Stephen Mellor, seemed to have a
                  pretty sensible approach. He said "I live in a state machine, and I'm quite
                  happy living in a state machine", thereby narrowing his focus to an
                  important subset of applications. He also was not wedded to UML, but just
                  wanted some language that let him specify his models. His group has actually
                  worked out semantics for doing this using subsets of UML to provide action
                  semantics, etc. People with his perspective might turn this into a useful
                  specialty technique.


                  Domain-specific languages (DSL)
                  -------------------------------
                  I like this concept (and discussed it in my book, page 272), but I have
                  reservations. The problem in practice, usually, is that the DSL is
                  disconnected from the programming language it is built on. The distinction
                  between using the language and developing the language is not sharp, as they
                  coevolve and insight deepens. (Well, it is forced to be a sharp distinction
                  in such an environment.) It is hard to continue refining the domain-specific
                  language once programs have been written in it. Debugging is hard. IDEs,
                  test frameworks and refactoring tools don't exist.

                  Developing a set of well abstracted objects or other constructs in the
                  general programming language can also provide developers with an expressive,
                  specialized language. True, the syntax will not be tailored, but the
                  syntaxes of general languages are not that bad if you work at making the
                  design supple. Smalltalk is better for this than Java because there is so
                  much less incidental clutter. The functional languages, such as the LISP
                  family, allow programmers to devise seamless DSLs. Some new language might
                  make this situation much better.

                  The distinct DSL does have its areas of applicability, especially when the
                  DSL can be peculiarly stable, when it is a scripting language for control by
                  end users or an embedded processor.


                  Specific solutions for narrow problems
                  --------------------------------------
                  I was quite interested in a few people who were not trying to create a grand
                  new technology, but were working on model-driven solution to a specific
                  problem that comes up all the time in OO Programming: tracking change
                  through time. "Time Conscious Objects" are ordinary Java objects
                  (potentially preexisting) with some extra behavior attached by their code
                  generator. These TCOs automatically keep a history of their attributes. They
                  can compare attributes at different points in time, and all sorts of other
                  neat tricks. They get a lot of powerful behavior out of a quite simple
                  addition to the code because they have found a deep model within this narrow
                  generic domain. The paper is interesting
                  (http://portal.acm.org/citation.cfm?id=949344.949376&dl=portal&dl=ACM&type=s
                  eries&idx=949344&part=Proceedings&WantType=Proceedings&title=Conference%20on
                  %20Object%20Oriented%20Programming%20Systems%20Languages%20and%20Application
                  s). This is in early development, but I hope it will eventually be useful to
                  many projects.

                  Imagine if we had such powerful yet simple solutions to even five basic OO
                  modeling challenges. There is more than one way to raise the level of
                  abstraction of programming. This really has me thinking.


                  Domain-Driven Design, the book
                  ------------------------------
                  OOPSLA 2003 was the debut conference for my book, and a lot of people seemed
                  to be interested. It sold well at "publisher's alley". I've asked the
                  Addison-Wesley rep to post the actual sales rankings here when he gets the
                  information.
                • Robin M. Roos
                  Hello Everyone Thanks, Eric, for the heads-up regarding Time Conscious Objects (see OOPSLA 2003 observations ). I ve jumped through hoops at the ACM website
                  Message 8 of 9 , Nov 24, 2003
                  • 0 Attachment
                    Hello Everyone

                    Thanks, Eric, for the heads-up regarding Time Conscious Objects (see "OOPSLA
                    2003 observations"). I've jumped through hoops at the ACM website and
                    finally, after shelling out the fee, hope to get the article tonight!

                    I thought the list might be interested in another initiative in this area.
                    I believe that the time-dimension of temporal objects (or, to be precise,
                    BOTH time dimensions) are orthogonal to the domain itself. The explicit
                    modelling of time variance makes for non-intuitive reference navigation and
                    horrendous query filters!

                    Ogilvie Partners has commenced an initiative to provide support for
                    transparent time variance through JDO (sorry - JDO again!). This approach
                    will remove infrastructure coding relevant to time variance from the domain
                    model. To read about our initial ideas please visit
                    www.OgilviePartners.com. Click on the link "Time Variance for JDO". There
                    are five short pages on the topic. Perhaps the most interesting one to this
                    group will be the "Worked Example" page.

                    Comments are welcome.

                    Kind regards, Robin.

                    [ See http://www.OgilviePartners.com for information about JDO and my book,
                    "Java Data Objects" ]
                  • patrickdlogan
                    Other time and history related ideas.... Several entries at PLoP 98... http://jerry.cs.uiuc.edu/~plop/plop98/final_submissions/ And the incomparable Ralph
                    Message 9 of 9 , Nov 24, 2003
                    • 0 Attachment
                      Other time and history related ideas....

                      Several entries at PLoP 98...

                      http://jerry.cs.uiuc.edu/~plop/plop98/final_submissions/

                      And the incomparable Ralph Kimball. The articles are about star schema
                      database design, but they are worth understanding even for a 100% OOP
                      system...

                      http://www.ralphkimball.com/html/articles.html

                      -Patrick
                    Your message has been successfully submitted and would be delivered to recipients shortly.