Announcement Announcement Module
Collapse
No announcement yet.
Merging service layer and DAO layer into single layer Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Just to add to this, doesn't the Template Method design pattern ring a bell? Adopting this pattern means usually the domain and dao layers are usually roled into one. This is a common pattern and is widely accepted.

    Having the domain and dao layers separate usually means that the Strategy design pattern is used. This is more popular. You'll find that the use of the Strategy pattern is more flexible to use and is helpful when developing large scaled apps.


    Shah.

    Comment


    • #17
      Solution to Service-Dao pass through methods

      I was searchig for a solution to exactly same problem. After a long time, came up with this solution utilizing dynamic proxy and spring FactoryBean interface. Find the solution at this link (i.e. my blog) http://ramesh-sahoo.blogspot.com/

      Comment


      • #18
        Very nice thread.

        Actually, i found it, as i was naively wondering if the use of JPA (instead of IBatis) had an impact on the good old architecture (presentation -> service -> DAO).
        Eventually, i was wrong doubting this architecture viability just because of an other data access implementation. That's what not also this thread tells me, but my common sense also at the end.
        We are often get so troubled facing with new techno, that it sometimes makes you confused and losing your beliefs. This thread has the advantage of replace things to their right place. To say, counting on his own experience and not dogmas, not focusing on technology mermaids but using it as a mean not an aim.

        Thanks for reminding me the cape, captain CONSTV !!

        Comment


        • #19
          What about transaction boundaries?

          Hi,

          I'm also struggling with the "proper" DDD-way of doing things. By proper I mean finding out how it fits into the rest of the world, rather than dogmatically applying everything I find in the net. I think we need to discuss more specific topics to gain a better understanding.

          I'm still half-way through the book and here's my take on things:

          My understanding is that DDD is all about your business tier. It doesn't mention much (at least as far as I've got) about other aspects such as the presentation/services tier.

          I'd expect that writing a DDD application is not so different in those regards, other than the fact that perhaps you've moved some (or a lot) of business logic into the domain and there's less in the services tier.

          So here's one concrete question: How do you handle transaction demarcation in DDD?

          Let's say you have methods on your domain objects that allow them to (agnostically) access persistence through repositories. Who do you allow to make such calls? Do you make the domain object @Transactional and allow anyone to use them (e.g. even the presentation tier)? After all, what's the point of having an order.save() method if the controller has to go through a service to use it? But isn't that a violation that pollutes the domain model with persistence implementation information? Ok, it's just an annotation, but the domain object suddenly becomes able to define a transaction boundary for some code path that ends up invoking a DB/JMS/... resource that it is unaware of.

          Coming from a "traditional" background, I favor clear separation and require that client code (e.g. presentation tier code) goes through some transaction boundary (e.g. a @Service in your services tier). The result of my approach was that after injecting "repositories" into my @Configurable domain objects, I couldn't get to them from my presentation tier unless I violated my principle of starting transactions at a clearly-defined boundary in my application... So I tried to keep the transaction boundary and realized that I must have taken a horribly wrong direction when I started writing stuff like:

          Code:
          Order order;
          // ...
          pubic void handleButtonPressInPresentationTier() {
               // order.processOrder(); <-- this would fail as it's not @Transactional
               orderService.submitOrder(orderDomainObject); // this is @Transactional
          }
          But then in the services tier:

          Code:
          // this service class is @Transactional
          
          // ...
          
          pubic void submitOrder(Order orderDomainObject) {
               orderDomainObject.save(); // ends up calling repository
          }
          So then, why not inject the repository into the service and NOT have a save() method in the domain object?

          Perhaps a middle ground would be to have domain objects annotated as @Transactional(propagation = MANDATORY). Then you can indirectly use resources at the domain object level (via the repository), while at the same time preventing direct access from any entry path (calling into the repository via the domain object requires that the client has already started a transaction, which is documented in the code via the annotation)...

          Then again, perhaps I'm still too "transaction-script-oriented" and am missing the point?

          Any comments on the above would be appreciated.

          Comment


          • #20
            akarypid, you bring up valid points. Not to revive this [at times somewhat inflammatory] thread, here's a "brief" answer:

            Transaction management is an application concern, not a domain concern... quite obviously. That is why it belongs in the "application layer" (the exact term used by Eric Evans, btw.) I personally have expressed my point of view many times in these forums: I don't think that persistence should be part of the Domain. In my opinion, it is very much an application-layer, use-case concern/implementation detail. DDD does not mean that all logic and persistence operations should be part of domain entities. It is the "DDD zealots" who, I think, take the idea way too far and fail to separate the essential object behavior from the application-specific logic that should - not contrary to what Eric Evans states in his book - live in the application layer. Services and repositories are part of the application layer. A domain "service" (or whatever you prefer to call an object that implements the logic that does not fit one particular domain entity but rather governs multiple domain entities in a context of particular application use cases) is the perfect point for transaction demarcation and domain-level security. (BTW, I would recommend defining transactions on the method level rather than on the class level.) Being part of the application infrastructure, repositories (or DAOs) should normally be abstracted within such "domain services." Spring provides very convenient stereotype annotations for such classes (@Service, @Repository, etc.) Note that none of this goes against the DDD principles. The most important thing, in my opinion, is to always properly separate the domain entity-level behavior from the application use-case level behavior. Failure to do so will result in a rigid domain model not reusable among applications within even the same enterprise. Implementing application use cases involves - usually - more than one domain class, may include transactional and secure operations, and should be implemented outside any given domain entity. That's what domain services (or whatever you want to call them if you hate the word "service") are for.

            HTH,
            Constantine
            Last edited by constv; May 18th, 2010, 08:19 AM.

            Comment


            • #21
              I love these old posts from Constv. I wish I had been working with the guy. Always clear and understandable real world explanations.

              Now, regarding this merging Dao into service issue, if following Constv's advice, I would need to have my service contain the following save method:

              Code:
              	public void save(Contact contact) {
              		contact = contactDao.makePersistent(contact);
              	}
              Somehow I'm not so impressed by my skimpy service method here.

              Should I have it return a boolean if the save fails ?

              Comment


              • #22
                Should I have it return a boolean if the save fails ?
                The signature of your service method should be determined by the type of contract you want the API to expose to the outside world. In some cases, the original object that is being saved might be updated to store a newly set - by the service - value (e.g. some id, status, or whatever.) If that is a possibility, it might be useful to return the object itself. Returning a boolean sometimes makes sense and sometimes adds no value. It all depends on your requirements. If failure to save means a critical error, an exception would be appropriate. If you really don't know what to do with it, I'd say leave it as is - you can always come back and change it once your requirements shape up. Don't rush to add complexity just for the sake of it. Simplicity has not hurt anyone. Unnecessary complexity - that's what kills projects. Good luck.

                Comment


                • #23
                  @stephaneeybert

                  "Should I have it return a boolean if the save fails ?"

                  No. In such case what you should do is throw a RuntimeException. You can define your own exceptions so that it is meaningful to your application (as long as it extends RuntimeException). Though there is a slight expense in using exceptions, it makes it easier to handle issues and makes for more meaningful stacktraces when you log those exceptions. So, if an SQLException is thrown within your DAO, wrap it with your RuntimeException and throw it back up the application stack. Capture it within your presentation layer and handle it from there (log it and display an error comfort page for example). In all, you get more value using exceptions.

                  Shah.

                  http://richdomain.org
                  Last edited by shahnawazshahin; Nov 24th, 2010, 03:24 AM. Reason: Modify signature

                  Comment


                  • #24
                    I just found out about Constantin's blog article on error handling at
                    http://articles.vconst.com/2009/08/e...s-in-java.html
                    What a gem.
                    Thanks guys.

                    Comment

                    Working...
                    X