Announcement Announcement Module
Collapse
No announcement yet.
Book: "Domain driven design" implemented in Spring Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • #46
    Originally posted by rebornspirit
    I also have a problem with the name DTO. These DTO's are actually always view on domain models, so why not just call them ViewObjects? Then we'll have DomainObjects and ViewObjects.
    I agree, that is a much more expressive name.

    I'm glad you take the ViewModes idea and turned it into something you can use. I haven't worked with Spring yet so I didn't consider the advantages of using it to resolve this. I just liked the discussion, but I will start checking out Spring though.

    Comment


    • #47
      The idea of Spring and Hiberante was to make the things much more simpler.

      Code:
      employeeDao.save(employee); //this one is questionable.
      Yes, this one is very questionable. In fact, it is quite disturbing. If we look at Data Access Patter (DAO) we can see that its main point is to separate the persistence (which is definitely not a business concern) from domain objects. Also, one of the basic OOP concept is that one object should have only one concern (as few as possible in practice). So, I completely agree that this logic should not be in a service (services deal with application logic and generally should be very thin layer). The Employee object should not have persistent logic inside:


      Code:
      class Employee{
         void fire(){
             Desk desk = getDesk();
             desk.clean();
             setStatus(FIRED);
             setSalary(0);
             setFiredDate(new Date());
          }
      }
      Then the service looks like that:

      Code:
      EmployeeService{
          void fire(Employee employee){
              employee.fire();
              employeeDao.save(employee);
          }
      }
      This will solve the problem that even if you call employee.fire() method in the view nothing too much will happen if you don’t call the appropriate service method. As a whole, if rich domain objects are implemented in such a way, calling method on a domain object in the view (I am not sure from whom :-), but let’s say …) would not be a problem, since the state of the object would not be persisted.

      Validation Logic:
      Most of the validation logic is actually a pure business logic. As a such, it must be implemented in domain objects.

      Code:
      class Employee{
         void setSalary(int amount){
      	Validator validator = ... retrieve salary validator
                  validator.validate(amount);
                  _amount = amount;
         }
      }
      So, everything is fine here. The only problem is that we have to retrieve something. I agree that in a rich domain object sometimes we need to retrieve some services or resource, but in this case we need validation (specification object). Why we don’t just use the very well known, old and simple way of just creating an object:

      Code:
      class Employee{
         void setSalary(int amount){
      	Validator validator =  new Validator(); 
                  validator.validate(amount);
                  this.amount = amount;//let's follow java convention.
         }
      }
      DTO/View Object

      The people that are raving about DTO or something similar have probably never used something similar in real project. Otherwise, they would’ve still felt the pain. DTOs are defined by many people as anti-pattern but even if they aren’t, the only appropriate place for DTOs is when we have remoting, which should be avoided on the first place.

      Another, thing against DTO is the Don’t Repeat Yourself (DRY) principle. How many times you have to write the same code before you realize that something is wrong. In case, you wonder, try changing some property in the middle of a project (for exampe: we change the type from string to enumeration, or we change money property from double type to specific Money type). You have to change all of the objects that copy one to another. This is a lot of work without any business value. We define a property in a domain object, than map it in a Hibernate file, than create this property even in a DTO, then bind the property of DTO to the view. How many times did we repeat the same code here?
      Also, an object has state and behavior. Where is the behavior in DTO? If you don’t have behavior, why you need this object on the first place. You can use some data structures like a map for example.
      If you continue using DTO or you have anemic model, why do you need POJO objects and why do you switch to Hibernate and Spring. You could’ve have the same unnecessary complex and very hard to maintain architecture with EJBs.

      Anyway, I don’t think that the architecture should be so complex:
      We have MVC.

      View - presenting domain objects. If something very, very different should be presented, then you probably have your domain model wrong. At the end, the view should present the domain model of the application.

      Controller – deals with user/application workflow. (do something- delegate the work to a service-if successful - go to another view – otherwise notify user)

      Model includes:
      - Service Layer – very thin layer (deals with application/infrastructure logic – transaction management, security and etc. – example: provide transaction management to dao and delegate the persistence to dao or sends an email notification and so on).
      - DAO – deals with persistence only. The main purpose is to separate persistence from domain objects.
      - Domain Model (domain objects) ALL business logic implemented here. Everything that you can think of business logic, including validations, business rules and so on.
      Since the whole application is built because of (around) the Domain Model, domain objects are presented in every layer (view, service, dao - probably not in the controller though).

      And YES, building true Domain Driven Architecture with good OOD is very hard an time consuming. Since our nature is to think more in procedural way and since many times we are pressured by deadlines, it is very, very easy to extract business logic all over the application.

      That’s why probably, we need a clean start like Ruby on Rails :-).
      Last edited by igorstoyanov; Nov 30th, 2005, 05:18 PM.

      Comment


      • #48
        Originally posted by igorstoyanov
        Code:
        employeeDao.save(employee); //this one is questionable.
        Yes, this one is very questionable. In fact, it is quite disturbing. If we look at Data Access Patter (DAO) we can see that its main point is to separate the persistence (which is definitely not a business concern) from domain objects.
        There is no persistence logic in the domain objects, only a call the the persistance logic. There is nothing wrong with that.

        And if you take another look at the example, you can see there is a desk involved. What if that desk need to be saved by the deskdao? Who is going to call the save?

        In your case it would be:
        Code:
        EmployeeService{
            void fire(Employee employee){
                employee.fire();
                employeeDao.save(employee);
                deskDao.save(employee.getDesk());
            }
        }
        In your case the Service would be aware of the internals of the employee and that is a bad thing.

        Also, one of the basic OOP concept is that one object should have only one concern (as few as possible in practice). So, I completely agree that this logic should not be in a service (services deal with application logic and generally should be very thin layer). The Employee object should not have persistent logic inside:
        It depends on how you define service. If you use the fowler definition, I agree. If you use the DDD definition, I disagree.

        Comment


        • #49
          Using Hibernate aware Domain objects in the web view for over 1.5 years now has thought me that using those kind of domain objects bring very specific problems like the evil LazyInitException!

          So responses to that problem where, initialize what you need in the service layer so that the LazyInitExc doesn't occur anymore. I think this kind of solutions is ten time worse then the DRY problem you have when implementing dto's. If I have a large object graph that is passed from my service to the web layer and I need to initialize some collections because of their lazy loading nature, then I have a coupling between my service and web layer!!! Because for an optimized graph were you do not load / init lazy stuff that you will not need in the web layer, you have a coupling, as simple as that! So if you want your large object graph to be used by all kind of views, you will need to fully init / load the object graph ... and that totally rules out the benefits of using hibernate lazy loading (which is in most cases a bless).

          Alse when developing products with an open api availble for your clients, would you return Hibernate aware domain objects? What if your client suddenly has a lazyInitException. Well ofcoarse we can in that case pre-init all the lazy data. But other problems like hibernate version or last modification data fields shouldn't be visible to the outside world .... so can't we agree that there is a difference between data you work with in and below the service layer and data we work in in the views? Anemic models should disappear from the scene and we should always use smart domain objects for all our logic... But I just get the explaination why we MUST use domain objects in the view, I find there is a fundamentally difference between a domain object and an object that represents a view on a domain model or a serie of domain models, I favor the lack of any kind of business logic that can be accessed through domain objects or whatever in the view, the view is for VIEWING things not for making business descissions... well that ofcoarse my 2 cents

          So ok, I know DTO's aren't the holy grail .... god bless for that ... and we need a better approach ... but we have got to admit that using hibernate aware domain objects in the web view isn't the right way to go!

          It would be great to hear from the Spring guru himself what he thinks about this so ROD IF YOU ARE READING THIS ...

          Perhaps we'll never agree on a solution but I guess this thread makes us think about a problem that in this stage of frameworks should already have been cleared out

          Grtz

          Comment


          • #50
            about DTOs and layers

            Originally posted by igorstoyanov
            DTO/View Object

            The people that are raving about DTO or something similar have probably never used something similar in real project. Otherwise, they would’ve still felt the pain. DTOs are defined by many people as anti-pattern but even if they aren’t, the only appropriate place for DTOs is when we have remoting, which should be avoided on the first place.
            I agree with your comments, but sometimes remoting can´t be avoided or the UI can't be plain html files. Suppose that the user interface is developed in C# using .Net technology (for rich clients that can't be based on a web app), and the core app is under JEE. The view need web services facades, core cannot export domain objects with that scenario.

            What is the best approach under that kind of architecture? My suggestion is to create a pure java facade (with domain objects) based on use case model, one for each actor. And then make another level of facade that fits with jax-rpc constraints (type/constructor constraints that don't belog to the model itself) to export web services using some java2wsdl tool.

            The objects for this second facade are DTOs for the domain objects of the inner facade, and we need assemblers o helper classes to build those DTOs...

            Any suggestions to avoid this extra work motivated by the use of web services for rich clients?

            Comment


            • #51
              I agree with your comments, but sometimes remoting can´t be avoided or the UI can't be plain html files. Suppose that the user interface is developed in C# using .Net technology (for rich clients that can't be based on a web app), and the core app is under JEE. The view need web services facades, core cannot export domain objects with that scenario.
              The architectures that you describe don’t shy with its elegancy. However, there are often cases like that in practice. This situation could be handled much better if web services are used or the whole architecture is developed as Service Oriented Architecture (SOA) instead of using remoting. Remember, the first rule in remoting is to try to avoid it if you can. So, whey you have SOA, you don’t have DTOs, rather you have messages. The whole concept is much different then, but you can find more information on the web.

              Code:
              employeeDao.save(employee); //this one is questionable.
              There is no persistence logic in the domain objects, only a call the the persistance logic. There is nothing wrong with that.
              DAO pattern is a good read. The main reason to use it to DECOUPLE the persistence concern from domain objects. The fact that you know how to retrieve dao is not responsibility of a domain object. This is very basic good practices, so if we don’t agree on that, than we have much different background :-).

              Code:
              EmployeeService{
                  void fire(Employee employee){
                      employee.fire();
                      employeeDao.save(employee);
                      deskDao.save(employee.getDesk());
                  }
              }
              A little knowledge of Hibernate will show that a best practice is to save children objects from the parent. So, in the case above if you save employee object, the desk object will be save as well. You don’t need the call deskDao.save(employee.getDesk());. Again, this is very basic practices for Hibernate and service implementation.


              If I have a large object graph that is passed from my service to the web layer and I need to initialize some collections because of their lazy loading nature, then I have a coupling between my service and web layer!!!
              I am not sure why you have coupling here. For every page, you attach/load the object to Hibernate session and populate/bind the view that you need.
              Anyway, there are many ways to deal with lazy loading problems - OpenViewSession is the first step. Another way is to use You will still have problems at some points, but there are many ways to solve them. One very elegant way of doing it is to use AOP:
              http://jroller.com/page/cenkcivici?e...s_to_hibernate

              Also, if you have so big problem with lazy initialization, you can have session-per-conversation:
              http://www.hibernate.org/42.html

              Anyway, there a lot of information about lazy initialization problems out there.

              Alse when developing products with an open api availble for your clients, would you return Hibernate aware domain objects? What if your client suddenly has a lazyInitException. Well ofcoarse we can in that case pre-init all the lazy data. But other problems like hibernate version or last modification data fields shouldn't be visible to the outside world .... so can't we agree that there is a difference between data you work with in and below the service layer and data we work in in the views?
              I am not sure what kind of scenario/product, this could happen. It looks to me that in this case again you need to provide services, which send messages to the client, instead of exposing domain object. However, there is a big difference in how you build normal application and how you build a product.
              Last edited by igorstoyanov; Dec 1st, 2005, 07:58 AM.

              Comment


              • #52
                Originally posted by igorstoyanov


                DAO pattern is a good read. The main reason to use it to DECOUPLE the persistence concern from domain objects.
                It is meant to seperate the core logic from the persitance logic, but it doesn`t mean a domain object can`t call a dao (imho). The DAO imho isn`t meant to decouple domainlayer from the data access layer, it`s goal is to seperate aspects.

                The fact that you know how to retrieve dao is not responsibility of a domain object.
                Well... that is one of the main points of this discussion

                A little knowledge of Hibernate will show that a best practice is to save children objects from the parent.
                What if that desk need to be saved by the deskdao?
                So.. we aren`t talking about hibernate but talking hypothetically. What if the desk also needs to be saved, whose responsability should it be? Should it be part of the personDao? And how deep should it check what to save? Hibernate helps a lot, but what if you are using plain-jdbc or ibatis? And should the semantics of the DAO-interface depend on the or-mapper used in the implementation?
                Last edited by Alarmnummer; Dec 1st, 2005, 09:45 AM.

                Comment


                • #53
                  Originally posted by rebornspirit
                  Using Hibernate aware Domain objects in the web view for over 1.5 years now has thought me that using those kind of domain objects bring very specific problems like the evil LazyInitException!

                  So responses to that problem where, initialize what you need in the service layer so that the LazyInitExc doesn't occur anymore. I think this kind of solutions is ten time worse then the DRY problem you have when implementing dto's. If I have a large object graph that is passed from my service to the web layer and I need to initialize some collections because of their lazy loading nature, then I have a coupling between my service and web layer!!! Because for an optimized graph were you do not load / init lazy stuff that you will not need in the web layer, you have a coupling, as simple as that! So if you want your large object graph to be used by all kind of views, you will need to fully init / load the object graph ... and that totally rules out the benefits of using hibernate lazy loading (which is in most cases a bless).

                  Alse when developing products with an open api availble for your clients, would you return Hibernate aware domain objects? What if your client suddenly has a lazyInitException. Well ofcoarse we can in that case pre-init all the lazy data. But other problems like hibernate version or last modification data fields shouldn't be visible to the outside world .... so can't we agree that there is a difference between data you work with in and below the service layer and data we work in in the views? Anemic models should disappear from the scene and we should always use smart domain objects for all our logic... But I just get the explaination why we MUST use domain objects in the view, I find there is a fundamentally difference between a domain object and an object that represents a view on a domain model or a serie of domain models, I favor the lack of any kind of business logic that can be accessed through domain objects or whatever in the view, the view is for VIEWING things not for making business descissions... well that ofcoarse my 2 cents

                  So ok, I know DTO's aren't the holy grail .... god bless for that ... and we need a better approach ... but we have got to admit that using hibernate aware domain objects in the web view isn't the right way to go!

                  It would be great to hear from the Spring guru himself what he thinks about this so ROD IF YOU ARE READING THIS ...

                  Perhaps we'll never agree on a solution but I guess this thread makes us think about a problem that in this stage of frameworks should already have been cleared out

                  Grtz
                  I see the same problems especially with Hibernate. Crap, I had different calls to get the same domain object, each retrieving different graphs because of that stupid lazyInitException. Personally, this is a brain dead and non-intiuitive approach. Actually, I try to avoid having complex domain objects because of these recurring issues when developing for web base applications. Personally, I never bought the argument that the domain object MUST be used in the view layer. If it maps one-to-one, then I'll use it. However, I would still create the evil DTO object (your "view object") for optimization and clarity reasons. It is even worse when you save domain objects. What do you recreate in the post action? A partial graph of the domain object? A full graph of the domain object?

                  dino

                  Comment


                  • #54
                    Hibernate helps a lot, but what if you are using plain-jdbc or ibatis? And should the semantics of the DAO-interface depend on the or-mapper used in the implementation?
                    No, the semantics of the DAO- interface should not depend on the ORM technology. That’s why we have interfaces and different implementation for them. Let say you have employer dao:

                    Code:
                    interface EmployerDAO{
                    	void save(Employer employer);
                    }
                    Then you have Hbernate implementation:
                    Code:
                    class HibernateEmplyerDAO extends SomeSpringClass implements EmpoyerDAO{
                          void save(Employer employer){
                    	getHibernateTemplate().save(employer); //this will save the desk object as well.
                           }		
                    }
                    Another implementation with jdbc or ibatis for example:
                    Code:
                    class SomeOtherImplementationEmplyerDAO implements EmpoyerDAO{
                          void save(Employer employer){
                    	someSaveMethodForEmployer(empoyer);
                    	someSaveMethodForDesk(employer.getDesk());
                           }		
                    }
                    So, you declare an interface that is behaving the same way regardless of the mapping technology.

                    Persistent Logic in Domain Objects

                    When you code according to OOP, you should think about object behavior. So, if you should have “fire” behavior, then you have:
                    Code:
                    Employee{
                        void fire(Employee employee){..}
                    }
                    I guess you would not put save() as a behavior to your domain object because it is not required from the business. But your object knows how to save –
                    Code:
                    employeeDao.save(employee);
                    Anyway, before you say that this behavior is encapsulated, lets move to the next situation when you don’t invoke fire() through a service, rather you invoke it through another domain object.

                    Code:
                    EmployeeManager{
                    	boolean isEmployeeForFire(Employee employee){
                    		employee.fire();
                    		//do other stuff (to count the employees that are left for example;
                    		//if number of employee/desk are less then expected
                    		 return false;
                    		else
                    		   return true;
                    	}
                    }
                    It is not very realistic, but I hope you get the point. So in this case, I am performing a operation, that could probably wait for approval from the user and then save the employee object. If we have performed the save already in the fire() method, it is going to be too late for approval or not.

                    Of course, you can again say you can avoid this and there is nothing wrong with persistence calls inside domain objects. I think that that’s why many of the people have a lot of problem with lazy initialize. The persistence mechanism should be implemented in DAO and should be performed in service with transaction managed when needed.

                    I see the same problems especially with Hibernate. Crap, I had different calls to get the same domain object, each retrieving different graphs because of that stupid lazyInitException.
                    I am not sure why you have these problems, and why you have different calls. I believe that a great deal of lazy initialization problems could be avoided, if you keep Hibernate session open for the time of the user interaction/request. I just want to clarify that I am talking mostly for web application. IF you keep the session open for the whole http request, then at least the first time of retrieving the object, you won’t have any initialization errors. Then, if you need to continue working with detached domain object, then you can re-attached to the Hibernate session in the beginning of every new request. The last one is not very recommend but if you have so many problems with lazy initialization, then this will be the easiest to do – refresh(), lock() or even update() would do the job.

                    Anyway, I think that the two framework Spring and Hibernate almost saved java and J2EE right now. They make thing simple, very productive and pleasure to work with. I am kind of surprised to see so many people having problems with Hibernate overall architectural design.
                    Last edited by igorstoyanov; Dec 1st, 2005, 07:57 PM.

                    Comment


                    • #55
                      Originally posted by igorstoyanov

                      I am not sure why you have these problems, and why you have different calls. I believe that a great deal of lazy initialization problems could be avoided, if you keep Hibernate session open for the time of the user interaction/request. I just want to clarify that I am talking mostly for web application. IF you keep the session open for the whole http request, then at least the first time of retrieving the object, you won’t have any initialization errors. Then, if you need to continue working with detached domain object, then you can re-attached to the Hibernate session in the beginning of every new request. The last one is not very recommend but if you have so many problems with lazy initialization, then this will be the easiest to do – refresh(), lock() or even update() would do the job.
                      I'm not a big fan of the keeping the session open throughout the request since it breaks encapsulation. What happens if you go to JDBC? What about scalability. Keeping a session around for a whole request cycle is awfully inefficient with sparadic n further SQL calls instead of a single joined sql statement. I think even Rod and Juergen are both against using such an approach. For practical reason, your approach is definitely usuable but I have a hard time justifying this from an architectural point of view.

                      Dino

                      Comment


                      • #56
                        Still, I believe it should be really about simplicity.

                        Since lazy loading is mostly Hibernate problem, I will start with this old post (2003) when Spring wasn’t very popular. In this blog, Gavin (I don’t want to start who said what) has expressed his opinion about this:
                        http://raibledesigns.com/page/rd?anc...ession_in_view


                        > However, I had just one technical quibble. Your persistence
                        > code starts and ends a transaction / Hibernate Session in
                        > every DAO method. I would have thought that
                        > transaction/session management should be done in a layer
                        > *above* the DAOs, so that we can group together multiple
                        > calls to the DAO in the same Session/transaction. It seems
                        > that you would end up with DAOs were much coarser-grained
                        > than usual, and would contain all the business logic for a
                        > transaction *inside* the DAO, instead of in a "Command" that
                        > calls the DAO.
                        >
                        > I usually split things as follows:
                        >
                        > Action = pageflow logic / session management
                        > CommandHandler = framework object that manages
                        > exceptions/sessions/transactions
                        > Command = business logic
                        > DAO = persistence logic (no exception handling/session
                        > management/transaction management)
                        Of course, Spring framework wasn’t very popular back then, but now we have Spring, which allows us to abstract database mappers to a great extend. In fact, I am a little surprised by your statement:
                        I think even Rod and Juergen are both against using such an approach.
                        This is from official Spring documentation with author Juergen Hoeller:
                        http://www.springframework.org/docs/...iewFilter.html

                        Servlet 2.3 Filter that binds a Hibernate Session to the thread for the entire processing of the request. Intended for the "Open Session in View" pattern, i.e. to allow for lazy loading in web views despite the original transactions already being completed.
                        You still can have more than one session if you are concern too much about scalability:
                        Alternatively, turn this filter into deferred close mode, by specifying "singleSession"="false": It will not use a single session per request then, but rather let each data access operation or transaction use its own session (like without Open Session in View). Each of those sessions will be registered for deferred close, though, actually processed at request completion.

                        A single session per request allows for most efficient first-level caching, but can cause side effects, for example on saveOrUpdate or if continuing after a rolled-back transaction. The deferred close strategy is as safe as no Open Session in View in that respect, while still allowing for lazy loading in views (but not providing a first-level cache for the entire request).
                        Anyway, many people have already talked about this topic many times. Very good explanation can be found in this blog:
                        http://www.jroller.com/page/cardshar...n_view_pattern

                        Some exerts:
                        Why use the Open-Session-In-View pattern? In short, it's the fastest and easiest way to solve the problems that typically arise from using Hibernate with ANY Model-View-Controller framework (including JSF, Tapestry, Struts, Spring, WebWork and plain old Servlet/JSP). Just what are those problems, you ask? By far the most common problems is the infamous LazyInitializationException.

                        For performance reasons, Hibernate encourages the use of Lazy Loading.
                        ………..
                        There are problems with this approach. Some developers have gone on record with scalability complaints with regards to Open-Session-in-View. I haven't seen these problems myself, but the number of threads on the subject suggest that the problem is real for some people. Others feel (myself included) that exposing a chunk of the persistence mechanism as a front-end filter is an architetural no-no. I can live with it because it's so transparent and so easy.
                        So, again there is no one silver bullet for every situation or architecture. However, for the most web application built out there, this approach to lazy initialization would be perfectly ok and much more efficient.

                        Keeping a session around for a whole request cycle is awfully inefficient with sparadic n further SQL calls instead of a single joined sql statement.
                        Yes in some situations. You can eagerly fetch the collections that are used most often or have more flexible approach of lazy/not-lazy initialization for some of the objects.
                        Anyway, this will very depend on the size of your object graph and how many of the objects in the graph you will use in a single request.

                        For practical reason, your approach is definitely usuable but I have a hard time justifying this from an architectural point of view.
                        Thank you. I can’t tell you how glad I am to here that. I mean, I prefer Agile methodologies in developing software application. I have more pragmatic view of what a good architecture is. So, if it is good for “PRACTICAL reasons” then this is good enough for me.

                        In the past, I also was raving about Big Upfront Design Architectures or something like that. I used DTO – not only for remoting but for normal web application to completely decouple the view from the domain and things like that. I saw a lot of inefficiency, lost productivity and most importantly, a lot of bugs because of having to manage so much repeating code around. I violated basic principle like DRY, good OOD with creating object that are actually data holders without ANY behaviors, but most importantly, I didn’t bring too much business value to my customers (I am a consultant) with the type of applications that are “justified from an architectural point of view”.

                        Now, I am questioning what a good architecture actually is. (BTW, not only me: Martin Fowler's keynote on OOPSLA 2005- "does good design even matter?":
                        http://ivan.truemesh.com/archives/000547.html ) So, I would say that if the architecture works well for your needs, it is easy to be refactored or modified (this totally excludes repeating code in almost every layer) and bring business value to the customer/user, then this sounds like a good architectural design to me.

                        Another good thing about Agile is TDD. One of its principles is not to write any code before you first write the test(specification) for the functionality(behavior) that is needed from your object. Try writing a test specifying behavior for DTO!

                        What happens if you go to JDBC?
                        Actually, I would never care about that type of question. If you start thinking about what could happen “IF something”, then you will build a lot of unnecessary code that would not bring too much business value to anybody. And probably (most likely) this “IF” will never happen, so you built it for nothing in 99% of the cases.

                        And yes, in some cases Open View Session would not be a good solution. In other application DTO probably will make sense (probably as properties in controllers, page beans or something similar but not as pure form of DTO). However, I feel that java community starts to loose a lot because of this over-engineering in every possible aspect. I will probably repeat myself but frameworks like Spring and Hibernate were created about simplicity. Let’s try to keep this spirit.

                        Comment


                        • #57
                          Originally posted by igorstoyanov
                          Thank you. I can’t tell you how glad I am to here that. I mean, I prefer Agile methodologies in developing software application. I have more pragmatic view of what a good architecture is. So, if it is good for “PRACTICAL reasons” then this is good enough for me.
                          I agree. I just wanted to point out that you are using Hibernate specific functionality and going from a different DAO implementation to another (like JDBC) would not be straight forward, if not possible. From that point of view, you are not really abstracting out the DAO layer properly. Does it mean that this is bad. Of course not. I've done this too. You are still able to TDD quite nicely from this practical approach (which is great and a more important goal IMHO). However, I still don't like the session-per-request approach but hey we can disagree on this!

                          Dino

                          Comment


                          • #58
                            TheServerSide.com article

                            Some additional discussion on TheServerside.com: Spring2 vs Anemic Model http://www.theserverside.com/news/th...hread_id=38047

                            Comment


                            • #59
                              Originally posted by Ben Alex
                              I take a different approach. In my domain objects I generally provide public getters, public setters if the property is not "state managed", and actual methods for modifying "state managed" properties, like fireEmployee(). Now if fireEmployee() should only be called as part of a transaction-controlled workflow, I use access modifiers to make it package protected. I put the services layer in the same package as the domain object. Sometimes we need state managed methods to be callable by other domain objects, like a BankAccount that has a changeBalance() method (because balance is "state managed") that accepts a Posting. Because Posting and BankAccount are different "aggregates" (as per DDD terminology - a very useful pattern in teaching people this stuff I find) we need an intermediate object for passing the Posting to the now-forced to be public BankAccount.changeBalance() method. So we create a posting.BalanceChangeRequest, providing a package protected constructor that accepts the Posting. The BankAccount.post() only accepts a BalanceChangeRequest. Thus you've effectively used access modifiers to extend package protection to the Posting package. I also use Hibernate field-level access, and overall it all works pretty nicely.

                              On the subject of reusing domain objects for DTOs and web form backing objects, I've found it not worth the hassle. Such form backing objects / DTOs can be created in seconds as they're just simple JavaBeans. It's more important to have a rich domain model that is infrastructure independent.
                              Interesting approach to limit access to only specific package. You probably made BalanceChangeRequest a final class?

                              Comment


                              • #60
                                another approach

                                Interesting thread and a lot of good replies. I'm hoping some of the folks on this thread could also comment on the approach I've taken to the whole problem of seperating domain layer and persistence layer using Spring, without having to inject DAOs into domain objects or having to call DAO persistence methods from the service layer.

                                Would appreciate some feedback on the same. My approach is published here - http://jroller.com/page/funwithjava?...model_solution

                                Thanks
                                Amit

                                Comment

                                Working...
                                X