Page 5 of 9 FirstFirst ... 34567 ... LastLast
Results 41 to 50 of 82

Thread: Book: "Domain driven design" implemented in Spring

  1. #41
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    Sounds like a workable solution!

    I would not add the ViewMode to the method signature of the service method, rather create specific beans where the correct ViewMode is set using the Spring context files.

    That we wa can indeed have the advantage of a DTO and have non project specific DTO's as a bonus, I can go with that!

    I think that the overhead of doing the cast is far from a problem, we are used of casting the Spring mvc command object so one more or less

  2. #42
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    So actually this is just the Assembler pattern by Martin Fowler.
    So for example we will have an interface that looks something like this:

    Code:
    public interface MyService {
        ViewObject getSomething(Integer id);
    }
    We will have a ViewObject assembler interface like:

    Code:
    public interface ViewObjectAssembler {
        ViewObject assemble(Object o);
    }
    Code:
    public interface ViewObject {
    }
    Code:
    public class MyCustomViewObject implements ViewObject {
    }
    The MyService interface implementation looks something like

    Code:
    public class MyServiceImpl implements MyService {
     
        private ViewObjectAssembler assembler;
    
        public ViewObject getSomething(Integer id) {
            MyDomainObject do = ... retrieve the domain object;
            return assembler.assemble(do);
        }
    }
    and a custom assembler being set by Spring:

    Code:
    public class MyCustomAssembler implements ViewObjectAssembler  {
    // handle the conversion 
    }
    and this class van for example be called by the controller like this:

    Code:
    MyCustomViewObject x = (MyCustomViewObject) myService.getSomething(new Integer(5));
    The ViewObjectAssembler can then be set in the application context of Spring on a project based approach.

    Comments are more then welcome

  3. #43
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    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.

  4. #44
    Join Date
    Sep 2004
    Location
    Manchester, UK
    Posts
    16

    Default

    Quote Originally Posted by rebornspirit
    - The domain model should hold as much as possible domain logic as possible. But sometimes to perform this domain logic, the model needs another dao or service and this is for the moment not simple to implement in Spring. I know they are working on it but it is still in the sandbox and I'm going to wait for it until it is in the releases.
    Could somebody point me in the right direction to find this in the sandbox please.

    This is a great thread BTW.

    Martin

  5. #45
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    Checkout DependencyInjectionInterceptorFactoryBean ... nice short name isn't it

  6. #46
    Join Date
    Nov 2005
    Location
    Buenos Aires, Argentina
    Posts
    2

    Default

    Quote 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.

  7. #47

    Default 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 at 05:18 PM.

  8. #48
    Join Date
    Nov 2004
    Location
    Hilversum - The Netherlands
    Posts
    1,054

    Default

    Quote 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.

  9. #49
    Join Date
    Oct 2005
    Location
    Belgium
    Posts
    87

    Default

    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

  10. #50
    Join Date
    Nov 2005
    Location
    Buenos Aires, Argentina
    Posts
    2

    Default about DTOs and layers

    Quote 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?

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •