Announcement Announcement Module
Collapse
No announcement yet.
DAO Reference Inside an Entity Domain Object? Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #31
    Hi,

    I'm joining this discussion because I have exactly the same problem. I have domain objects that have a child collection with several millions of childs.

    In this scenario, If I need, for example, the childs between a set of dates, I can't iterate on memory, and must therefore rely on hibernate. But for this to work on the domain object, I have to inject it with another service (the one that has the queries for the child entity)

    So I would like to discuss the opinion that injecting another service in the domain object is bad. I personally disagree, if done properly, using an interface and wired by spring I think it would be decent. It all boils down to the fact that if we want smart objects we have to given them something to work with...

    Another example I have is telling a report object to generate itself. I'm still thinking about that one, as it would force me to inject a dependency to the reporting factory, that has the services that generate reports.

    Hope the discussion can continue, looking forward to your opinions / experiences.

    Another "little" trouble, our domain objects need to be sent to the clients, that also access all operations.

    thanks
    Ricardo

    Comment


    • #32
      Just to cause some more "flame bait" Sometimes I think it is important to do the YAGNI and KISS thing, i.e. do the simplest thing possible.

      Most progress occurs *after* different flavours are tried out, so maybe we should bite our tongues and see how bad our different flavours really are.

      In a few months, hopefully experience will dictate the "best" way

      (quickly running away ....... )

      P.S. Of course I don't *really* mean this post, but sometimes just getting on with an imperfect solution is better than no solution

      Comment


      • #33
        Yes, of course. Our application works now, with service factories, and, because of client access to domain objects, will certainly have some issues with a richer domain model. but we're not discussing architecture in the air, we have working code we wish to improve

        Comment


        • #34
          show off; I still actually haven't gotten around to reviewing the code in question IFIRC I have a dedicated Service (actually just a DAO) with nasty methods .

          It is actually the action or command class that has all the collaborators, so some things are just not possible directly on the domain model.

          Comment


          • #35
            I fully agree on the possibility of including a DAO in a domain object. In my opinion, even a reference to a service can be considered legal. Suppose you want to split up your project into different components with every component containing a servicefacade through which every other object of another component communicates with. Wouldn't it be straightforward that domain objects of componentA can use the logic of componentB by using the servicefacade of componentB? I mean, if the call to componentB is part of the domain logic of a domain object of componentA, then why should this call be included in the service of componentA (instead of the domain object)? If it's part of the domain logic, it should be coded in the domain object.
            In my opinion there are 2 'kinds' of Services. The first kind of service is an implementation of a use case, it is application dependent. The second kind of service can be considered as a service which represents a facade of a component which is reusable through many projects/applications. The first kind of service should not be used by domain objects because that would imply that a domain object is dependent on application specific code. The second kind of service can be used by domain objects because it's a reusable component.

            I am not a very very experienced software engineer so correct me if I'm wrong :wink:

            Comment


            • #36
              Originally posted by yatesco
              Sometimes I think it is important to do the YAGNI and KISS thing, i.e. do the simplest thing possible.

              Most progress occurs *after* different flavours are tried out, so maybe we should bite our tongues and see how bad our different flavours really are.

              In a few months, hopefully experience will dictate the "best" way

              sometimes just getting on with an imperfect solution is better than no solution
              I agree with yatesco when he says "an imperfect solution is better than no solution".

              I initially agonized over these issues for several days (weeks?). The answers are not simple and straightforward, even for the experts (see my earlier posts in this topic). It seems that Rod Johnson's initial opinion was to move such logic out of the domain object and into a business service facade. Now, as indicated by his support of DependencyInjectionInterceptorFactoryBean, it seems like he's at least somewhat open to the idea of moving such logic back into the domain object to make it richer. To add further confusion, look at my earlier post that starts off "I asked Eric Evans...". If the experts can't agree, what can us poor mortals do?

              DependencyInjectionInterceptorFactoryBean seems like it may give us the best of both worlds: transparent dependency injection into objects hydrated by Hibernate AND richer domain objects. However, the last time I checked, DependencyInjectionInterceptorFactoryBean was still in Spring's sandbox. I'm not comfortable using it in production until it's in the main source tree and several people have tried it.

              So, until then, I'm using a technique similar to yatesco's ChildEntityLocatorStrategy (again, see earlier posts in this topic for details). In other words, I'm passing the "child lookup" service dependency to every invocation of the parent domain object's method. It's not the most elegant solution, but it's simple and it works. It allows me to keep the domain logic in the parent domain object and I don't have to worry about "auto magically" trying to inject domain objects when Hibernate hydrates them for me.

              Call me crazy.

              Comment


              • #37
                cyboc; your £5s in the post

                Comment


                • #38
                  Originally posted by yatesco
                  cyboc; your £5s in the post
                  Huh? Oh, are you calling me crazy? :lol:

                  Comment


                  • #39
                    Nope, I am paying you £5s for your compliment It is a joke, I am pretending I had to pay you for you to say you agree with me

                    Comment


                    • #40
                      I've spent a lot of time thinking through such issues as well, and it strikes me that many times we are really fighting against our tools, and then mistake this for philosophical differences. What if we completely forgot about the limitations of Java and Spring and instead focused on an "ideal" solution? In our imaginary solution, we may end up exceeding what is even possible in Java, but at least then we would know whether the debate of injecting service/facade/dao references into model objects is really about a development philosophy or about working around limitations in our tools (tools being Java, Spring, Hibernate, etc). Or whether the best answer is something else entirely that we aren't even considering now because our minds are trying to think within the confines of our tools.
                      As for the philosophy of it all, I think sometimes we developers take certain base OO principles too far. Remember, OO was roughly based on the real world. In the real world if I wanted a hamburger, say, then I, as an "object", have several options. I can go find a cow (another object), kill it, butcher it, grind it up, pack the meat together, and cook it over a grill. I can go to a store “service” and buy ground beef and go from there. Or, I can go to a McDonalds "service" and ask for a hamburger, at which point I will have to engage in a certain "protocol" of paying them money and they will produce the hamburger. I may not even have known in advance where the McDonalds was, and so may have been forced to ask a "collaborator" to help me find it. My point being that even in the real world we don't always expect objects to be completely self contained and all powerful – but I've seen many times where developers bend over backwards trying to make their objects completely self contained. Sometimes it makes sense, sometimes it doesn't. In each of those scenarios our main object had to interact with other objects and/or services in various ways to accomplish an end. I don't see these constructs as a compromise. Of course, some solutions are better than others depending on the situation, and so one must learn (through experience) when to use the various patterns we have available.

                      - Andy

                      PS My illustration breaks down, as one could argue that the main object, while not completely self-contained, was completely self-directed. But that's just a fault of my illustration.

                      Comment


                      • #41
                        adepue; what about vegetarians

                        Comment


                        • #42
                          I am in the process of learning spring and consequently the "new and better" style of coding which seems to consist of a heavy focus on a thick stateless service layer. The reading material makes a lot of this stuff sound great from a theoretical point of view and I think it does make sense for most things but I am currently struggling to figure how this particular issue can be managed. I would love to find the most common sense solution, so let me outline how i view this issue, unfortunately this is all pretty new to me so i don't have a solution.

                          A lot of domain models i have worked with are very layered. Where an object may have 3 or more layers beneath it. But at the very least every domain model has situations where an object has a child collection below it that you need to use heavily at times but at other times you barely use this data. For instance lets look at class A which has a child collection of class B objects.

                          Code:
                          public class A
                          {
                          private int id;
                            public int getId() {
                              return id;
                            }
                            private Collection bChildren;
                            public Collection getBChildren() {
                              return bChildren;
                            }
                          }
                          I find that because sometimes you need access to this child property and othertimes you don't it is nice to be able to lazy load this data from the stateful domain object. The advantage being is it doesn't have to do a db hit unless it needs it. But if it does need it you only have to hit the db once and you can use the data over and over.
                          Code:
                          public class A
                          {
                            private Collection bChildren;
                            private int id;
                            public int getId() {
                              return id;
                            }
                            public Collection getBChildren()   {
                              if (bChildren==null)//lazy load messy but at least it is hidden
                                loadBChildren();//domain object a hits database directly
                            return bChildren;
                            }
                          }

                          If you use a service layer I see problems
                          1)It seems much more natural to ask the parent object
                          2)Every time you need this data you have to make this service call:

                          Code:
                          public class A
                          {
                          private int id;
                          public int getId() {
                          return id;
                          }
                          //some code where a is in use
                          private A a;//used in code 
                          
                          public someMethod() {
                          //since a has no child property built in we just get b separately
                            Collection bChildren = aServiceObject.getBChildren(a.getId();
                          //do something with b children
                          }
                          
                          //more  code where a is in use
                          public someMethod() {
                          //Oh look we have to get b again, lots of db hits....
                          Collection bChildren = aServiceObject.getBChildren(a.getId();
                          //do something with b children
                          }
                          Of course there is an alternative. This is where things get interesting. From what I have read the common solution being suggested is that you set this child collection as a property on the parent object once you get it. Some reading, for instance see chapter 11 of pro-spring suggests that if you are getting a finder on the parent class then you should not load the child data because you are mass loading the parent and don't know exactly which one you need. However, on a single load of the parent you do get the children because in this case you are focusing on this one object. Essentially load the data when you would more likely need it. Sounds good but...well lets look at the code first

                          Code:
                          public class A
                          {
                          private int id;
                            public int getId() {
                              return id;
                            }
                            private Collection bChildren;
                            public Collection getBChildren() {
                              return bChildren;
                            }
                            public void setBChildren(Collection b) {
                              this.bChildren =b;
                            }
                          
                          }
                          
                          //in A's Service Object
                          
                          public Collection getLotsOfAs(args...)
                          {
                          //just get the As without B children
                          Collection lotsOfAs = findAs(args...)
                          return lotsOfAs;
                          }
                          
                          public A getA(int id)
                          {
                          A aToReturn = getA(id);
                          aToReturn.setBChildren(getBChildren(id));
                          return aToReturn;
                          }
                          But I think this is really dangerous and can lead to a lot of confustion. Because how do you really know whether the child property was set? Especially once the A object gets passed around from place to place? i think this produces buggy code, when the state of bChildren property is always in question. Everytime you access it you would have to check to see if it was null and if so load it.

                          I think this is a very common situation, So then there must be a good solution.???

                          Comment


                          • #43
                            I've haven't read this thread from beginning to end so I suspect I'm going to get flamed for this... Deep breath.

                            Be pragmatic. Do this:

                            Code:
                            public class A
                            {
                              private int id;
                              public int getId() {
                                return id;
                              }
                              private Collection bChildren;
                              public Collection getBChildren() {
                                if (bChildren == null) {
                                  bChildren = aServiceLayer.getBChildren(id)
                                }
                                return bChildren;
                              }
                              public void setBChildren(Collection b) {
                                this.bChildren =b;
                              }
                            }
                            Ollie

                            Comment


                            • #44
                              Originally posted by oliverhutchison
                              I've haven't read this thread from beginning to end so I suspect I'm going to get flamed for this... Deep breath.

                              Be pragmatic. Do this:

                              Code:
                              public class A
                              {
                                private int id;
                                public int getId() {
                                  return id;
                                }
                                private Collection bChildren;
                                public Collection getBChildren() {
                                  if (bChildren == null) {
                                    bChildren = aServiceLayer.getBChildren(id)
                                  }
                                  return bChildren;
                                }
                                public void setBChildren(Collection b) {
                                  this.bChildren =b;
                                }
                              }
                              Ollie
                              I am kind of chiming in late too but thanks for the reply.

                              I believe what you are suggesting is to make the Domain Object aware of the Service Layer. From all my reading, supposably, this is bad form and generally deemed evil. You service layer is on top of your domain layer so the domain object should never be aware of the service layer.

                              However, this is essentially how i have been coding in the past, my domain objects have full db access and the service layer is embedded within them. I find this method very convenient, but it does leave all your domain objects as rather heavy classes that aren't very portable.

                              Comment


                              • #45
                                As long as you services layer is defined with an interface there's nothing to fear.

                                You're free to switch and swap whatever implementation you like dependent on the requirements you have at the time - in a rich client you'd probably implement your services layer using remoting, on the server you'd probably plug a transactionally advised services implementation directly into the domain object, in a test? plug in a mock - you get the idea.

                                However, this is essentially how i have been coding in the past, my domain objects have full db access and the service layer is embedded within them. I find this method very convenient, but it does leave all your domain objects as rather heavy classes that aren't very portable.
                                embedded? that sounds scary...

                                What I'm suggesting is that it's OK to have dependencies from your domain objects to your services as long at they are abstract. Any concrete dependencies (DB access is very concrete) are probably bad, but there can be exceptions.

                                And forget about some ideal architecture KISS YAGNI!

                                Ollie

                                Comment

                                Working...
                                X