Announcement Announcement Module
Collapse
No announcement yet.
2005 all over again - domain driven design, where are we? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #16
    Regarding Wicket and GWT : it is true that they "easily" let you code complex UIs, but they have IMHO a great flaw : they make separation of concerns useless, forcing developers to produce a lot of Java code.
    Could you elaborate on what you think is wrong with the GWT separation of concerns?

    Why need developers need to produce a lot of code, those full bloated JSP pages aren't a pretty sight either ... but you have to write something don't you a gui doesn't appear on the screen with some magic trick. But if you need to decide between JSP, tags, ... or a fully maintainable, testable GWT, I think I'm going to take the GWT road, I've made just TOO many complex business web apps to not see the GUI creation / maintenance / testing problems. Things tend to get more complex every project, and I don't thing fighting complexity with a scripting or tag related language is going to help us lowering time-to-market.

    It's not clean to keep the complete session open
    Why do you say that?
    Hibernate is a persistence strategy and keeping the principles of layered designs in mind being the bottom layer should not be depended on the top layer, well ... keeping the session open in the view gives you a dependency on your persistence strategy, what if you switch to JDBC or iBatis, you will need to make adjustments to your view layer, no?

    Repositories have a different granularity than DAOs: there's usually one repository per aggregate root, because root entities are the only one with independent lifecycle, while other entities should be "saved" and "retrieved" through their relative root entities.
    I also use injection of repositories for complex aggregates. But I must admit that for simple entities, I sometimes use the DAO directly. For complicated aggregates, repositories contain domain logic in addition to accessing the DAOs for data fetching purposes. And the contract for the Repository nicely abstracts away all these complications from the actual entity. From that point of view, ONE repository can *contain* MULTIPLE DAOs, each corresponding to the respective table in the database. And finally, I use interfaces as the contracts for repositories
    I'm old school, like to see things instead of reading abstract explanations about something ... so ... could you provide us a few lines of code showing exactly how you use the dao and how the repository combined with your domain model? Thanks ;-)

    Here's some other post I wrote in responding to almost the same scenario presented to justify DTOs. On top of that, I'd say that, yes, it would be cleaner to have a specific view model, but that kind of cleanness should not come at the price of a fragile service API/implementation (unless justifiable by some significant performance gain). In other words, I would assemble the view model from DO's in my presentation layer, not the service layer - which makes it just a view model, not a DTO.
    That was exactly what I was talking about, or at least was thinking of :-) Working with DTO's / view models (or whatever name is may have) will force you to have its own layer on top of the service layer. A layer which is responsible for assembling view models out of multiple domain model data retrieved from multiple service. I'm doing this currently for my GWT application, my GWT app does ajax calls to my application services, which are responsible for assembling my view models. It looks very clean and having done multiple years of business web apps I know the hell of changing domain models which cause views (jsp or so) to break or at least hard to maintain.

    Some other random thoughts
    - So you have designed the company business into your domain model, it all looks great, the idea will serve for years... BUT (yes there is always a 'but' in IT lolz) business rules tend to change faster than project can be completed. So what about using domain models in combination with rule engines i.e. Drools, anyone has any good or bad experiences with that?

    Comment


    • #17
      Here are some of my thoughts regarding injection of DAOs or Repositories in domain entities ..


      Cheers.
      - Debasish

      Comment


      • #18
        I was wondering if some of us actually tried to implement DDD? Or are we still where we were in 2005?
        Seems like if there was a good way to *implement* it rather than write about it then we'd all be doing it by now.

        The @Configurable approach arguably just creates an AOP injected Ball-Of-String (AOP BOS)

        The furthest we've taken DDD is to implement methods which can make use accessible Hibernate properties (many-to-one, set, etc,), so if for example a Hibernate domain object method would otherwise need a DAO injected we put the method in the DAO, not the domain object (anti-DDD).

        Comment


        • #19
          Noob-DDD

          Hi,

          I am also a struggling recoverist from acute anemicdomainsm trying to grasp DDD (especially in the mvc/spring/orm context). I tried to partially implement a very simple domain with an Order which can add OrderRows based on Products. The "core" method in Order looks like this:

          Code:
          	public void addOrderRow(String productName) throws DuplicateProductException, OrderAlreadyProcessedException {
          		if (productAlreadyInOrder(productName)) {
          			throw new DuplicateProductException("Product " + productName + " already in order");
          		}
          		if (orderAlreadyProcessed()) {
          			throw new OrderAlreadyProcessedException("Order " + orderNumber + " is already processed");
          		}
          		Product product = repositoryLocator.getProductRepository().fetchProductByProductname(productName);
          		OrderRow newRow = OrderRowFactory.createRow(product, rows.size() + 1);
          		rows.add(newRow);
          	}
          * Should the Product added be looked up by the Order or should the caller pass in the looked up Product?

          * Should the row number be passed to the OrderRowFactory in that way?

          And the calling action looks something like

          Code:
          	public void addProductToOrder() {
          		try {
          			currentOrder.addOrderRow(selectedProductName);
          			serviceLocator.getPersistenceService().persist(currentOrder);
          		} catch (DuplicateProductException e) {
          			e.printStackTrace();
          		} catch (OrderAlreadyProcessedException e) {
          			e.printStackTrace();
          		}
          	}
          * Should the persistance be the responsibilty of the callee?
          * Should the repositories do all their DB access through a DAO or can they have a DAO-like implementation themselves? (please see attached code)

          Please see the attached zip for "complete" source. e.g. it compiles but hasn't been run in any way. JPA and spring mappings have been left out and there are many simplifications but hopefully you get the point. The post would be too long if I posted them all in text.

          Am I at all heading in the right direction regarding the design and dao/repository/service concepts? Comments are appreaciated!

          Comment


          • #20
            Originally posted by Nik View Post
            * Should the Product added be looked up by the Order or should the caller pass in the looked up Product?
            I don't think that this could be answered for a general case, but it looks ok to me as you've done it.

            Originally posted by Nik View Post
            * Should the row number be passed to the OrderRowFactory in that way?
            I wouldn't expect an addXXX method to take a row number argument. In any case, if it is not domain relevant I would omit it.


            Originally posted by Nik View Post
            * Should the persistance be the responsibilty of the callee?
            In my opinion yes. Persistence operations should not be placed inside model objects themselves. That should be handled by repositories. Besides that: When using ORM you can achieve to save dependent objects together with their root object by appropriate mapping declarations.

            Originally posted by Nik View Post
            * Should the repositories do all their DB access through a DAO or can they have a DAO-like implementation themselves? (please see attached code)
            As I see it, "repository" and "DAO" are practically the same.

            Regards,
            Andreas

            P.S.: I recommend "POJOs in Action" by Chris Richardson which covers these aspects quite well.

            <Edit>
            P.P.S.: I would refrain from using a service locator as you do in your code as it is more difficult to test. An alternative is passing in the needed objects as parameters.
            </Edit>
            Last edited by Andreas Senft; Feb 28th, 2007, 06:28 AM.

            Comment


            • #21
              Thanks for the reply.

              Originally posted by Andreas Senft View Post
              I don't think that this could be answered for a general case, but it looks ok to me as you've done it.
              It doesn't look that nice when the adding method takes a string (a Product would make the association more clear) but I think that would result in code leaking out into the calling action. And if there would be more code in the callee, it should be moved somewhere (a service?), but in both cases logic is moved away from the domain object...

              Originally posted by Andreas Senft View Post
              I wouldn't expect an addXXX method to take a row number argument. In any case, if it is not domain relevant I would omit it.
              I lost you there. The add method doesn't take an argument but the order is the only one to know the row number of the next row (relevant in ordering the rows).

              Originally posted by Andreas Senft View Post
              In my opinion yes. Persistence operations should not be placed inside model objects themselves. That should be handled by repositories. Besides that: When using ORM you can achieve to save dependent objects together with their root object by appropriate mapping declarations.
              Yep. Although sometimes the ORMs can be a pain in the neck when you have some contraint on the table that is violated becase the ORM decides to do updates and deletes in certain order etc.

              Originally posted by Andreas Senft View Post
              P.S.: I recommend "POJOs in Action" by Chris Richardson which covers these aspects quite well.
              Yep, its on my (slowly advancing) reading list...

              Originally posted by Andreas Senft View Post
              P.P.S.: I would refrain from using a service locator as you do in your code as it is more difficult to test. An alternative is passing in the needed objects as parameters.
              Could you elaborate? I usually find it handy just to inject a common root locator so you can have access to any service without rewiring.

              Comment


              • #22
                Originally posted by Nik View Post
                It doesn't look that nice when the adding method takes a string (a Product would make the association more clear) but I think that would result in code leaking out into the calling action. And if there would be more code in the callee, it should be moved somewhere (a service?), but in both cases logic is moved away from the domain object...
                As I said, no general solution...


                Originally posted by Nik View Post
                I lost you there. The add method doesn't take an argument but the order is the only one to know the row number of the next row (relevant in ordering the rows).
                That was my point. I interpreted your question that you thought about adding a row number to the signature.


                Originally posted by Nik View Post
                Could you elaborate? I usually find it handy just to inject a common root locator so you can have access to any service without rewiring.
                If you want to test a method that uses a locator (usually a static method) then your test inevitable tests the locator functionality as well. You cannot test in isolation which is especially uncomfortable when this requires infrastructure as database access or the like.
                When you pass in your repository (or what else) you are able to mock that dependency in your test, enabling you to have isolated test cases.
                This is also elaborated on in the book I mentioned.

                Regards,
                Andreas

                Comment


                • #23
                  I am still trying to wrap my head around the benefits of DDD. The main concern I have - my domain objects are directly accessed by the view layer (JSPs). By implementing business logic on our domain objects, are we not creating a security risk by possibly exposing sensitive methods to the client?

                  Comment


                  • #24
                    Originally posted by craig.schneider View Post
                    I am still trying to wrap my head around the benefits of DDD. The main concern I have - my domain objects are directly accessed by the view layer (JSPs). By implementing business logic on our domain objects, are we not creating a security risk by possibly exposing sensitive methods to the client?
                    Well, it's not like the users can do XSS and execute arbitrary methods on the objects. Or?

                    Comment


                    • #25
                      I am not sure i follow this, what exactly is this trying to solve? It seems to me like it is rebelling against current trends just for the sake of being different, not really making it easier to deliver quality software faster. Hell nobody here really even knows how to do it, which tells me it is a probably a suspect concept. If it did make sense we should have lots of well known examples and be using it by now. But I hope I am missing something.

                      What exactly is wrong with the anemic domain model? Seriously I'd like someone to answer that one because it really hasn't been addressed here yet. Isn't having the logic to

                      addOrderRow() throws 18BillionExceptions {
                      useLotsOfDependencies();
                      }

                      outside of the model in a service better seperation? And how is "repository" different from "business service" which both use 1 DAO and N services to provide a higher level interface? Same thing different name...

                      Instead of the controller calling the service, it calls the model, which calls the service (er repository .. if thats what you want to call it to feel better about it). Where is the benefit of that?

                      I've always thought of the domain objects as books on a shelf, when I need to manipulate a set of books I ask the librarian, yelling at the books doesn't do much. Now you are saying the books should have eyes and ears, so I talk to them and they talk to the librarian for me. I hope I am misunderstanding because that just sounds like foolishly reshuffling everything for no reason.

                      But I am with you on the modify a domain property -> break view page thing, that sucks. And I don't even see how that would solve this. Your view will still reference _some_ object, and eclipse won't detect changes to it no matter what useless layer you decide to put it in.

                      Comment


                      • #26
                        which tells me it is a probably a suspect concept
                        I agree. I call "shennanigans" on domain driven design.

                        Comment


                        • #27
                          Originally posted by lloyd.mcclendon View Post
                          What exactly is wrong with the anemic domain model?
                          Well, in my opinion an anaemic domain model is not really following the OO paradigm. An object has to contain data and operations on that data (i.e. behavior). And getters/setters do not really count as behavior.

                          I think it has been the advent of EJB which forced using anaemic domain models as EJBs poorly addressed fundamental OO concepts as hierarchy and polymorphism. Besides that, the proposition of entity beans prevented efficient augmentation with behaviour, so putting everything in services instead.
                          As this model became ubiquitous for quite a while, the "real" OO approach has been forgotten and is now resurfacing within the DDD movement.

                          And the benefit? The idea of tying data and behaviour together is to provide cohesion which facilitates understanding of the code and it also improves maintainability.

                          Just my 2 cents,
                          Andreas

                          Comment


                          • #28
                            Well, in my opinion an anaemic domain model is not really following the OO paradigm. An object has to contain data and operations on that data (i.e. behavior). And getters/setters do not really count as behavior.
                            DDD is nonsense because as soon as you introduce the idea that an object behaves differently depending on its context the idea of bunging every single possible method into it becomes stupid.

                            DDD might work for a bunch of little objects which:
                            - aren't used across VMs
                            - aren't used in messaging
                            - don't care about performance
                            - etc.

                            Data just simply isn't suited to OO treatment, otherwise like above, if it was meant to be it would have been done by now.

                            I'd be looking for a completely new approach to make DDD work -- trying to shoehorn it into OO isn't going to work, not while there are networks, messaging queues, databases, and application performance, etc. to deal with.

                            Comment


                            • #29
                              Originally posted by gmatthews View Post
                              DDD is nonsense because as soon as you introduce the idea that an object behaves differently depending on its context the idea of bunging every single possible method into it becomes stupid.
                              I never suggested to put "every single possible method" into an object. And which context are you referring to? Do you mean by context where an object is being used (server, client, ...)? I think by applying sensible design rules there shouldn't be that big problems. I suggest to have a read to the DDD book by Eric Evans and "POJOs in Action" by Chris Richardson. That might make things a bit clearer.

                              Originally posted by gmatthews View Post
                              Data just simply isn't suited to OO treatment, otherwise like above, if it was meant to be it would have been done by now.
                              So I take it you are suggesting to return to the procedural programming paradigm again?

                              Originally posted by gmatthews View Post
                              I'd be looking for a completely new approach to make DDD work -- trying to shoehorn it into OO isn't going to work
                              DDD has OO as its foundation (as also stated in the books mentioned above), so I daresay it would be difficult to use it without that. But if you can come up with a new approach feel free to share it here. It is always beneficial to evaluate different viewpoints.

                              Regards,
                              Andreas

                              Comment


                              • #30
                                I've read the book

                                So I take it you are suggesting to return to the procedural programming paradigm again?
                                Sometimes OO, sometimes procedural -- but not everything will be in the style of Object->Operation();

                                A toolkit called Voyager, which existed maybe 7-8 years ago had a novel approach where you could acquire an interface to some aspect of the object.

                                e.g.

                                invoiceObj.persistenceOf().save();

                                This seemed to acknowledge that object lives in different spaces (e.g. client/server like you mentioned) and that sometimes an aspect wasn't available.

                                e.g. .persistenceOf() might return null.

                                I'd be more accepting of DDD theory if it provided examples based on more complex system architectures than 3 or 4 objects running in a single VM.

                                I think the only way forward out of DDD nonsense land is for someone to specify a non-trivial system with multiple VMs, databases, queues, web + rich client and then for someone to implement what they consider to be a DDD solution.

                                i.e. show me some real non-trivial solution instead of waffling and flailing about.


                                ----

                                follow up..

                                ----

                                As a follow up, what I don't get is "what's the point of DDD" -- my code is already mostly OO, its readable, its maintainable, it works pretty fast, so why bother going to extra mile?

                                I'm actually more interested in getting my hands on the Spring OSGi implementation and seeing how that impacts software architecture rather than taking DDD to the n'th degree.
                                Last edited by gmatthews; May 18th, 2007, 04:46 AM.

                                Comment

                                Working...
                                X