Protecting the Domain Model

Discussions

News: Protecting the Domain Model

  1. Protecting the Domain Model (70 messages)

    In a prior blog, Anssi Piirainen discussed using data transfer objects as a way of safeguarding presentation code from a domain model, but in "Protecting the Domain Model," he discusses ways to make the domain model itself more effective.

    Among them are:

    • Avoiding anemic mutators
    • Ensuring that only domain logic is in the domain
    • How one might evolve the architecture
    Start simple and use the domain model throughout the the system, including the presentation and other types of clients. This way you will be enjoying the benefits of the domain model everywhere. Your client code will appear to be speaking the domain specific language.

    He also mentions signs that your domain model might be brittle and that it's time to refactor a bit.

    How do you address your domain models? How do you prevent anemic domain models without relying on tools such as Xdoclet (or do you worry about anemic models at all?)

    Threaded Messages (70)

  2. Protecting the Domain Model[ Go to top ]

    We had attempted to use domain models that were tied to our persistence layer before and found it quite difficult to adapt long term (which is what Hibernate somewhat promotes).

    We are taking a much simpler approach now with Domain Objects that wrap DTOs and basically delegate all state to them. This has lots of advantages such that the internal DTO's setters aren't exposed to clients of the Domain model directly. This allows application specific behavior to be used before modifying the inner DTO instance.

    Now that we've worked through some development using this approach of "Domain Object has a DTO", our applications are much simpler in relation to persistence management and coordinating data transmissions.

    I wrote a bit on the subject in my blog.
  3. DTOs got a bad rap[ Go to top ]

    I would agree that DTOs have gotten a bad rap. In projects past we used DTOs very successfully. Our web tier (servlets or actions as controllers) would code to the data in the DTOs and nothing else. We sent back both reference type data as well as transactional data inside of each DTO.
         The DTOs were very specific to each screen and only carried the information truly needed by the screen.
    This was a great advantage for performance. Also, we could populate the DTOs from a variety of sources, the mainframe, EJBs, whatever, without the client caring. As such, when we had to change how the DTOs got populated ... no changes were ever required of the web tier. If the business wanted to add a new field to the web tier often it was no more than adding a field to the DTO and to the code that populated the DTOs.
         We actually took the concept quite a bit further and created a "framework" (ugh ... tired of hearing that word) that could gen DTO classes based off of the Domain Model. Transfer of values from the POJO BOM objects into the DTOs was all handled "automagically" including data type conversion. Performance was very nice and the POJO BOM contained no code that dealt with the DTOs. The decoupling of the tiers was the best part though as we had an agrred upon contract in the DTOs.

    regards,
         Adam
  4. DTOs got a bad rap[ Go to top ]

    I have to agree with your analysis. In our previous project we tried to use "domain objects" in the UI (as suggested by the hibernate people). It was a mess in the end because the domain object doesn't really match the UI. You end up adding a whole bunch of hiddens to represent the domain object so you can call the saveOrUpdate method (worse yet you get lazy instantiation errors when trying to display the domain object: anyone using hibernate knows what I mean).


    -- Dean
  5. DTOs got a bad rap[ Go to top ]

    I have to agree with your analysis. In our previous project we tried to use "domain objects" in the UI (as suggested by the hibernate people). It was a mess in the end because the domain object doesn't really match the UI.
    Then what are you trying to represent with your UI?
    The problem doesn't lie with the technique.
     You end up adding a whole bunch of hiddens to represent the domain object so you can call the saveOrUpdate method
    Hmmm. Sounds like you might be using the wrong UI technology.
     (worse yet you get lazy instantiation errors when trying to display the domain object: anyone using hibernate knows what I mean)
    Nope. But I know where the problem is. :(
  6. DTOs got a bad rap[ Go to top ]

    I have to agree with your analysis. In our previous project we tried to use "domain objects" in the UI (as suggested by the hibernate people). It was a mess in the end because the domain object doesn't really match the UI. You end up adding a whole bunch of hiddens to represent the domain object so you can call the saveOrUpdate method (worse yet you get lazy instantiation errors when trying to display the domain object: anyone using hibernate knows what I mean).

    I've run into this problem, and I didn't find it too difficult to overcome. Simply expose different getters and setters to Hibernate and the UI. Since Hibernate can read private getters/setters, I use these for values that I want exposed to Hibernate but not the UI:

    private Set getCategorySet() ...
    private void setCategorySet(Set set) ...

    I expose the same values in a different way to the UI, and deal with lazy instantiation by try/catch in the getters:

    public Category[] getSubcategories() {
        try {
            int size = this.getCategorySet().size();
            Category[] category = new Category[size];
            this.getCategorySet().toArray(category);
            return category;
        } catch (Exception ex) {
            return new Category[0];
        }
    }

    I admit that for very complicated domain models, there would be a value for DTOs, and if you need them you can define them. For the simple 90%, though, it is nice not to have to add this extra code.
  7. DTOs got a bad rap[ Go to top ]

    Hibernate also sets field attributes. Since, to me, Hibernate is "rehydrating" objects, I have no problem with this.
  8. DTOs got a bad rap[ Go to top ]

    We have used Hibernate POJOs directly in presentation tiers (both Web and Swing). We have solved technical problems with lazy initializations by converting Hibernate Collections to standard Java collections before sending data to a remote client. Also, we have the upper class for all POJOs that have a couple of extra attributes that help with the saving. We have implemented our own save method in "cascade=all-delete-orphan" style which saves only the data that has truly changed in the client.

    All this stuff is implemented in a couple of helper classes (by using reflection). Hibernate is a great technogy but it's stupid that it doesn't offer much support for remote (Swing) clients that need to handle the POJOs outside the session. Also, it's stupid that many great books (like Domain-Driven-Design from Eric Evans) mostly ignore the problem (when to use domain objects and when value objects in a client application). I hope these gurus would remember that all the systems are NOT web applications running in a single JVM.
  9. DTOs got a bad rap[ Go to top ]

    Tomi,
      I'm with you on this. But I wouldn't put the blame on Hibernate (or such tools). I would put it on the web app craze. But it is a problem that needs to be addressed now that Swing and SWT (and whatever JSF might render) apps are on the rise.

      Anyway you could share more on what you did? Could be the basis of a good article to post here.
  10. Hibernate helper class[ Go to top ]

    Briefly what I did...

    1) Before returning data in DAO a method DAOHelper.initData(Object) is called. The method converts Hibernate Collections to corresponding Java Collections (for example org.hibernate.collection.PersistentSet -> java.util.Set). The method uses reflection to search Collections via getters.

    2) When saving data in DAO I call DAOHelper.storeRecursively(MyEntity, Session). The class MyEntity is upper class for POJOs including fields "changed", "deleted" (+ a couple of customer-specific field that are included in every database table). The method storeRecursively executes Hibernate session methods (save, update, delete, flush) and handles other POJOs in the given MyEntity.

    Both the methods work recursively, meaning that all nested POJOs and Collections found via getters are handled. Of course there are performance and scalability issues that must be thought carefully when using these methods and sending nested POJOs back and forth between a client and a server application. I'll think about writing an article about the solution...

    BTW, JavaWorld is about to publish my article about TikeSwing 20th of June (a Swing framework with POJO and high-level MVC support).
  11. Hibernate helper class[ Go to top ]

    What's the point of converting Hibernate collection to
    java.util.Set? You can mark the hiberernate class to eager load the collections (although performace wise it will not be that
    great)

    Briefly what I did...1) Before returning data in DAO a method DAOHelper.initData(Object) is called. The method converts Hibernate Collections to corresponding Java Collections (for example org.hibernate.collection.PersistentSet -> java.util.Set). The method uses reflection to search Collections via getters. 2) When saving data in DAO I call DAOHelper.storeRecursively(MyEntity, Session). The class MyEntity is upper class for POJOs including fields "changed", "deleted" (+ a couple of customer-specific field that are included in every database table). The method storeRecursively executes Hibernate session methods (save, update, delete, flush) and handles other POJOs in the given MyEntity. Both the methods work recursively, meaning that all nested POJOs and Collections found via getters are handled. Of course there are performance and scalability issues that must be thought carefully when using these methods and sending nested POJOs back and forth between a client and a server application. I'll think about writing an article about the solution... BTW, JavaWorld is about to publish my article about TikeSwing 20th of June (a Swing framework with POJO and high-level MVC support).
  12. Hibernate helper class[ Go to top ]

    What's the point of converting Hibernate collection tojava.util.Set? You can mark the hiberernate class to eager load the collections (although performace wise it will not be thatgreat)

    The problem is that Query gets the result as an ArrayList but if the result POJO includes a Collection of other POJOs, that Collection is (always?) a Hibernate Collection. I wouldnt want to put hibernate.jar, odmg.jar etc. to my Java client classpath.

    I have tried to find solution for this issue, but probably searched in wrong places... and ended up writing code to do the conversion. How do you set class to eager? Can you give me a link or short example of this?
  13. Hibernate helper class[ Go to top ]

    Best to use a left join fetch in HQL query to eagerly fetch the parts of your domain object that you actually want. Remember you don't want to eagerly fetch everything or you'll end up retrieving half the database on every query!

    See www.hibernate.org for more on this, or get Hibernate in Action (I'd recommend this).
  14. Hibernate helper class[ Go to top ]

    Best to use a left join fetch in HQL query to eagerly fetch the parts of your domain object that you actually want. Remember you don't want to eagerly fetch everything or you'll end up retrieving half the database on every query!See www.hibernate.org for more on this, or get Hibernate in Action (I'd recommend this).

    Yes, we use left joins (and left outer joins etc.) and we get all the data we need from the database. But the problem is that I don't want any org.hibernate.collection.PersistentSets in the result because I'm sending the result to a Java client running in a workstation. I want to stick to pure POJOs and I don't want my client to know anything about Hibernate.

    So is there a way to ensure that the result of a Hibernate query contains ONLY plain Java classes? Or do I need to do the conversion by myself. (Any Hibernate gurus around? Gavin?)
  15. Hibernate helper class[ Go to top ]

    My apologies!

    I've been mulling over the idea of a Spring AOP interceptor (like the Spring transactional proxy interceptor to manage Hibernate transactions) that intercepts all responses from a business facade object and removes all Hibernate collections. It could use reflection to check every field for Hibernate Collections or lazy classes, and replace them with null or an empty set.

    You'd want such a proxy to act at a precise point where Hibernate objects become detached - that's why I think it would work well with the business facade pattern.

    I imagine somebody's already written such a thing, or is it a stupid idea for some reason I haven't thought of?
  16. Re: Hibernate Helper[ Go to top ]

    A Hibernate helper is one idea. Adding to this ... what is really needed is a smarter lazy initialization layer that can be distributed between the client and server. Most web apps use the session in view pattern so they can fetch more data as they determine it is needed. However, this concept is blown apart when you detach and serialize the object to a client elsewhere. As a result people try to use reflection to make sure their objects are fully populated. While this works, it is like taking a hammer to the situation. What really needs to happen, is that the lazy initialization layer is able to intelligently fetch objects across the client/server divide. However, this has its own set of problems.
  17. Hibernate helper class[ Go to top ]

    Martin,

    I agree that Facade pattern would work well. We are using session bean as a facade that invokes services via reflection. Service are POJOs that delegate database operations to DAO classes. Before returning data from a service we convert Hibernate Collections so that a client always handles domain objects that are plain Java classes. You're right, the facade (or proxy) could automatically get rid of Hibernate classes.
     
    In client-side we are using these domain objects inside view model classes. The domain objects are mapped directly to view components. The domain logic is in the domain objects, but client-specific code is in the MVC classes using those objects. We are using this approach with Swing and JSF applications.

    In general, if we stick to pure POJOs, I don't see any point in creating separate transfer objects. Of course a service may return value objects (I mean the Value Object term that Eric Evans uses) that can be considered as transfer objects when serialized. But I don't think converting all the domain objects to separate transfer objects (and vice versa) in every remote call is the way to go. The client framework just has to be good enough to handle domain objects in the right way (catching possible setter exceptions, marking changed objects etc.)
  18. Hibernate field access[ Go to top ]

    The Hibernate team seem pretty against this but I think it usually makes perfect sense. In most circumstances I can't see any point in having private getters and setters just for Hibernate, when they don't do anything other than access and change the private field. Setting access="field" in the Hibernate mapping has exactly the same effect.

    Things would be different if the private getters and setters actually did something. Maybe if you didn't own the database a setter could check for invalid values and assign a default value to the field and log the problem (throwing an exception probably wouldn't help matters much).

    Having private getters / setters also, annoyingly, means that you can't have public ones with the same name. And the public ones are the useful ones that you might actually want to do things like throw exceptions on invalid values.
  19. DTOs got a bad rap[ Go to top ]

    That doesn't take into account all data referenced by your Category instances. You end up with a duplicate set of references to whichever dependant persistent objects each Category has. That also happens to be the reason why all DTO/ValueObject mumbo conducted that way is broken.
  20. Protecting the Domain Model[ Go to top ]

    An intersting approach that I've used is an Abstract Domain Model.

    Define abstract relationships between your entities,aggregates and value objects ( in the Martin Fowler sense ), flesh them out using aspects depending on the context of the usage of these domain objects.

    Keep simple logic inside the abstract classes of your domain logic, but more complex state can be delegated to tier specific customisations.
  21. I wonder why your post didn't get the attention of magnitude what people discussed over the DTO a.k.a. Transfer(/Value)Object pattern that is nothing more than /An object that carries data between processes in order to reduce the number of method calls/ according to Fowler. Extending the purpose to for example visualization of data goes way beyond of the focus. To me this pattern is usable along with Domain Model when data transfer is not transparent enough and optimization is needed. Hibernate, JDO, and many other implementations covering the Domain Model (try to) reduce significally or obsolete the need for the DTO. But still this is no antipattern. There just a clear when to use definion, that specifies wether implementation is a strategy of the pattern or something completely different.

    I'd my self like to hear more about this Abstract Domain Model if people have some opinions.

    I'm not that big fan of aspect oriented programming, neither are extensively layered approaches near to my heart, but if the extra complexity is really worth of something then why not.
  22. Ugh[ Go to top ]

    I see so many articles like this that say very little, and what they do say is
    almost entirely a strawman argument. Here's the only real concrete example
    from the blog entry:
    For example if your Customer object stores an address it probably should not expose setters for individually assigning the street address, the zip code and the country. Instead the address should be modeled as a separate Address object and the Customer should have a setter that takes the Address as a parameter.
    This is year-one no-sh*i-Sherlock stuff that any amateur should understand.
    It's basic data modelling and 99% of the time, code that has de-referenced
    entities inside other entities (address elements as part of the customer)
    isn't badly designed or in need of improvment; it's wrong and it's
    broken and whoever wrote it needs to be taught proper data modeling and
    basic programming.

    In other words, there isn't some big fancy design pattern needed to "solve
    this dilemma"; it's a basic tenent of data design (2nd normal form?) that
    would be reflected in your object design.

    The problem with making a mountain out of this molehill is idiotic rules like
    "no anemic mutators" [ where 'anemic' apparently means getting/setting
    primative types ]. Your database stores strings and numbers and so your
    Domain Objects are going to store strings and numbers. Your Domain Object
    get/set methods are necessarily going to be mostly "anemic" mutators. The
    term and the rule are both silly.


    The "recipies for success" are also laughable, as they are first-grade OO
    Design tenents that anyone throwing around terms like "DTO" and "Domain Model"
    should already know. They are compounded by the mis-use of the term "Domain
    Model". A Domain Model is just that, a Model, not a bunch of code.

    This article really doesn't say much of anything at all, and only a
    high-school aged budding programming could glean anything useful from this.

    Yet another reason that The Server Side is so laughable as a technical
    resource.
  23. Ugh[ Go to top ]

    This article really doesn't say much of anything at all, and only a high-school aged budding programming could glean anything useful from this.

    Yet another reason that The Server Side is so laughable as a technical resource.
    That's fair. However, don't you think that articles like this help "budding programmings" (sic) turn into more competent "programmings?" I mean, sure, some of it's obvious - I didn't think that anemic mutators was all that earth-shattering, personally.

    However, so many things are done poorly in enterprise programming, someone has to expose things that other people consider to be basic or else things will ALWAYS be done poorly.

    Dave, what would YOU like to see on TSS? Would you like to contribute content?
  24. Something about TDD. Is it good or bad? Do people use it?
  25. Ugh[ Go to top ]

    The problem with making a mountain out of this molehill is idiotic rules like"no anemic mutators" [ where 'anemic' apparently means getting/settingprimative types ]. Your database stores strings and numbers and so yourDomain Objects are going to store strings and numbers. Your Domain Objectget/set methods are necessarily going to be mostly "anemic" mutators.

    I don't want the database completely control the way I model my classes. I want to enforce business rules and those rules may dictate that individual bits are not directly changed using mutators. This is basic OO desing.
  26. Ugh[ Go to top ]

    it's a basic tenent of data design (2nd normal form?) that
    would be reflected in your object design.

    Well, it's clear to me that you're the one that should be taught basic object oriented design, since you obviously derive the object model from the data model... which is conceptually wrong, even if the end result in some cases is correct. Academically speaking, you should create the best OO design possible and derive the data model from it. In real life, you should create the best OO model, the best data model, and derive second versions of both after negotiating the pros and cons each has considering the non-functional requirements your system has.
    That is: if the best OO design means having a poorly-performant SQL query to retreive an object tree from a realtional database (model mistmach blah blah), and you are not a purist, feel free to break the perfect OO model in order to improve performance.
    Purists write books; pragmatists build systems.

    Cheers and happy coding,
    Martin
  27. Anti-pattern is right![ Go to top ]

    All DTOs do is add complexity and unnecessary constraints. I've used domain objects and DTOs and there is no reason for DTOs unless you're using an Entity Bean. Just serialize your domain object and pass that to the presentation tier. I'm surprised how many people are afraid to send a domain object to the presentation tier. Seems everyone wants to create a new object just for display. Create a helper class if you need to format your data just right. Don't put in the domain object and don't create a DTO just so you can have your domain in all String values.
  28. Anti-pattern is right![ Go to top ]

    +1.
  29. Anti-pattern is right![ Go to top ]

    +1. give the domain model to the GUI and if needs a new model, it's up to it to adapt. Of course send only the slice necessary to the GUI to avoid serialization.
  30. Anti-pattern is right![ Go to top ]

    +1. give the domain model to the GUI and if needs a new model, it's up to it to adapt. Of course send only the slice necessary to the GUI to avoid serialization.

    So how do you only send the slice that is needed if you don't send it in a DTO? Only partially fill in the domain objects? If you partially fill in the domain objects, on a per screen basis, then you do have a DTO - just named the same name as the domain object.

    thanks
       Adam
  31. Anti-pattern is right![ Go to top ]

    It was suggested before by JC (In a responce on the blog) that you create an interface just for the methods you want available to the presentation tier. This would allow you to provide the front end only a slice of the domain object.

    FYI You don't need to convert your Hibernate collection to another collection...just use Hibernate.initialize() to load the collection items.
  32. Anti-pattern is right![ Go to top ]

    Even an interface that only identifies the necessary fields is essentially a DTO. When I think of DTO I think of it as more of a pattern ... it doesn't necessarily have to mean a separate object or a class. In short, the DTO concept is sound, only send to the client what it really needs and don't let that knowledge blowback into the domain model.

    thanks,
      Adam
  33. Anti-pattern is right![ Go to top ]

    It was suggested before by JC (In a responce on the blog) that you create an interface just for the methods you want available to the presentation tier. This would allow you to provide the front end only a slice of the domain object.

    I don't like the idea of covering your domain objects with interfaces that are client specific... However, I like the concept of only showing certain methods to certian clients.

    Crazy idea: What if you used AOP to weave those particular interfaces on the domain model objects before sending them to the client. That way the client only works with the interfaces and the fact that an actual domain object is implementing them behind the scenes is a detail.

    Floyd
  34. Anti-pattern is right![ Go to top ]

    It was suggested before by JC (In a responce on the blog) that you create an interface just for the methods you want available to the presentation tier. This would allow you to provide the front end only a slice of the domain object.
    I don't like the idea of covering your domain objects with interfaces that are client specific... However, I like the concept of only showing certain methods to certian clients.Crazy idea: What if you used AOP to weave those particular interfaces on the domain model objects before sending them to the client. That way the client only works with the interfaces and the fact that an actual domain object is implementing them behind the scenes is a detail.Floyd
    Cool. An AOP Chastity Belt. :)
  35. Anti-pattern is right![ Go to top ]

    However, I like the concept of only showing certain methods to certian clients.Crazy idea: What if you used AOP to weave those particular interfaces on the domain model objects before sending them to the client. That way the client only works with the interfaces and the fact that an actual domain object is implementing them behind the scenes is a detail.Floyd
    Neat idea with the AOP. Actually, ... prior to AOP we tried a prototype where we built the DTO classes "on the fly" by generating their bytecode. It was a neat experiment, that was unfunded by the way! :^)
    It worked in theory but was much less practical than just generating the java source for the classes. Developers easily picked up on the idea of the DTOs. Having the source sitting around allowed devs to debug through the DTOs if they had a problem - the "dynamic" approach didn't lend itself towards that.
  36. Anti-pattern is right![ Go to top ]

    Quite commonly a UI only requires data from a single domain object. In this scenario we would benefit from automated generation of the presentation layer directly from the domain model (be it via interfaces or objects).

    However, UIs often need to present in a single view data coming from more that one domain object. This leads to the need for hand-coded view-specific presentation objects (usually DTOs) that aggregate the required data to be displayed.

    There may also be some circumstances in which the presentation layer objects/interfaces can not easily be automatically derived from the domain objects, warranting a hand-coded version of the presentation object for the view.

    An effective framework would automatically generate most of the presentation layer from the domain model, then you would be left with a few views which we would have to hand-code.
  37. Anti-pattern is right![ Go to top ]

    All DTOs do is add complexity and unnecessary constraints.

    IMHO not any more complexity than helper classes.
    I've used domain objects and DTOs and there is no reason for DTOs unless you're using an Entity Bean. Just serialize your domain object and pass that to the presentation tier.

    What happens when your domain model changes? You should be able to make sweeping changes to your domain model in support of business process without touching your client (UI) code.
    don't create a DTO just so you can have your domain in all String values.

    Agreed. We didn't use the DTO just for this function. Essentially the DTO becomes the contract for the screen and can be populated however we want behind the scenes.

    thanks,
       Adam
  38. Anti-pattern is right![ Go to top ]

    I've used domain objects and DTOs and there is no reason for DTOs unless you're using an Entity Bean. Just serialize your domain object and pass that to the presentation tier.
    What happens when your domain model changes? You should be able to make sweeping changes to your domain model in support of business process without touching your client (UI) code.
    Yes this is true but if your making sweeping changes to your domain model then you're probably also changing your views. This concern is unfounded. Once your app is up and in production you are most likely not doing to make radical changes to you domain model. If so it's a sign it was flawed from the begining. Most likely you will be only adding a few columns and those changes will mostlike be cause by the end user wanting a new field on the screen.
  39. Anti-pattern is right![ Go to top ]

    Yes this is true but if your making sweeping changes to your domain model then you're probably also changing your views.
      Not necessarily. Part of an app that we wrote was the progressive conversion of a mainframe application to a J2EE application. All of the screens had to be built day one but the middle tier was to be replaced over a series of a couple years (as the mainframe app was decomm'd). We built all of the screens day one, backed by DTOs, and then swapped the middle tier out at our leisure. The views didn't change for years but the layers underneath constantly did.
    <br>
    This concern is unfounded.
      No, it really isn't. I've seen many applications where the GUI code was so intimately tied to the domain model (and vice versa) that estimates to make business logic changes ballooned because of the incestuous nature of the code.
    <br>
    Once your app is up and in production you are most likely not doing to make radical changes to you domain model.

      Probably true for most applications during their maintenance period. But what about when the app gets upgraded or has signifcant functionality added to it? For apps that don't require a strong decoupling of their tiers then I would agree that DTO can be overkill.
    <br>
    If so it's a sign it was flawed from the begining.
      Hardly. Most applications are not "green field" applications. If only to find a "green field" application contract ... sigh. :^) Decoupling of the tiers in an N-tier solution has been a proven IT technique since the 70's. It makes good sense that you can change one component in isolation of another.
      In most green field apps when they go to prod, the screens match what the middle tier contains, time tends to "warp" this relationship as the application gets upgraded though. Let me ask you, "Do you use struts"? and "Why don't you use your JDBC ResultSet directly in your JSPs"?
      You use struts because it separates responsibilities between the MV&C, right? It would be easier to just use the ResultSet returned from the JDBC connection inside the JSP but most people place data retrieved by JDBC into a bean that gets used by their Action and their Form. The whole point of the exercise is to decouple the technology that got you the data from the data it got. This is all done in the event that JDBC got "swapped out" in the future lieu of something other technology (JMS maybe?).
      I would argue that you will change your business logic more frequently than you will switch between JDBC and some other technology yet the isolation still gets used widely by web programmers today. IMHO the same isolation is valid for domain objects against the presentation tier.
    <br>
    Most likely you will be only adding a few columns and those changes will mostlike be cause by the end user wanting a new field on the screen.
      Maybe for apps where the business logic doesn't change for large periods of time. However, applications that support allowing the business to very quickly adjust both what composes a domain object model and how it interacts with other domain objects are becoming quite popular. "Screens" in an application don't necessarily draw their data model from one or two domain objects, their actual number can be be many. If a change happens to even one domain object that change could get pushed to many UI components even unknowingly.
    <br>
    Also, as an aside, we've seen a marked increase in performance by truly only sending what's needed by the web tier across the wire (via the DTO). Domain object models have a tendency to get very large (by their nature as they do contain state information). Most of this information isn't relevant to every screen that they might get sent to as a screen may only need one piece of info from the domain object, not its life history!
  40. Anti-pattern is right![ Go to top ]

    Also, as an aside, we've seen a marked increase in performance by truly only sending what's needed by the web tier across the wire (via the DTO). Domain object models have a tendency to get very large (by their nature as they do contain state information). Most of this information isn't relevant to every screen that they might get sent to as a screen may only need one piece of info from the domain object, not its life history!

    Yes, but domain object models don't need to be filled. If a User object has a field for an Address object, you can have 2 methods in a business facade:

    User findUser(String emailOrIdOrWhatever);
    User findUserWithAddress(String emailOrIdOrWhatever);

    So long as it's well documented, this shouldn't cause problems, and it saves on creating a load of extra classes just for data transfer.
  41. Anti-pattern is right![ Go to top ]

    Yes, but domain object models don't need to be filled.
      So your domain object now becomes your DTO, which will be filled differently for each screen. How does that get documented versus knowing exactly what is expected to be in a DTO?
    So long as it's well documented, this shouldn't cause problems, and it saves on creating a load of extra classes just for data transfer.
      Just my .02cents but I'd rather have "extra" classes that are designed for a single purpose than domain objects that have methods for use on a per client basis.

    thanks,
      Adam
  42. Anti-pattern is right![ Go to top ]

    I think it works well with the facade pattern - the only interaction that the web tier (or other tier) has with the business tier is through one or more facades. The methods on the facade are written specifically to cater for the use-cases of the tier in question. Typically one screen on a web interface would need one method in a facade (to minimize network transfer and to allow batching of database access).

    I see your point about the type-safety of DTOs. I too like the idea of the web tier not having access to any methods that won't work. But at the same time I don't like the duplication you get with a DTO approach - I guess it's just a question of figuring out which is worse...
  43. Anti-pattern is right![ Go to top ]

    But at the same time I don't like the duplication you get with a DTO approach - I guess it's just a question of figuring out which is worse...
    Neither did I. We got around the duplication by using a tool that handled the monotony of the DTOs for us (or at least we made it transparent). As annotation supoprt gets widely accepted as part of 1.5, I'd be willing to wager that we'll see lots more tool support along these lines for j2ee.

    -Adam
  44. Anti-pattern is right![ Go to top ]

    Yes this is true but if your making sweeping changes to your domain model then you're probably also changing your views. This concern is unfounded. Once your app is up and in production you are most likely not doing to make radical changes to you domain model. If so it's a sign it was flawed from the begining. Most likely you will be only adding a few columns and those changes will mostlike be cause by the end user wanting a new field on the screen.

    I think it is normal that the domain model is not perfect after the first version is shipped to production. When implementing the first version you have gained a lot of knowledge. That knowledge could be incorporated into the domain model and it might mean sweeping changes for it. These changes might be necessary if the changed model makes it easier, for example, to add new features or if a lot of existing code will be simplified (or can be removed). A good domain model is efficient in implementing it's logic.

    These kind of changes don't necessary mean that you must add new fields to the screen. Therefore I think it would be nice if you could make refactoring without the clients being affected.
  45. Anti-pattern is right![ Go to top ]

    Therefore I think it would be nice if you could make refactoring without the clients being affected.

    How is this an argument for DTO?
  46. Anti-pattern is right![ Go to top ]

    DTO is one way to make refactoring easier so that the clients are not directly affected.
  47. Anti-pattern is right![ Go to top ]

    Just serialize your domain object and pass that to the presentation tier. I'm surprised how many people are afraid to send a domain object to the presentation tier. values.

    There's good reason to use DTOs, even if you're not using entity EJBs.

    First, what happens if your domain objects have complex or bidirectional relationships? Serializing an object like that over any remote link, whether it's RMI, SOAP, etc. is a bad idea, because it will recursively pull and serialize all reachable objects from the one you want.

    Second, if you're assuming your web and business tiers are in the same JVM and serialization is not a concern, you still have to deal with lazy-loading. "Open Session In View" is a good-enough 80-20 workaround. But it kind of sucks to have to keep a DB connection open during presentation layer rendering--especially if your client is on a 56k dialup link. :-)
  48. Open Session in View[ Go to top ]

    "Open Session In View" is a good-enough 80-20 workaround. But it kind of sucks to have to keep a DB connection open during presentation layer rendering--especially if your client is on a 56k dialup link. :-)

    And it sucks even more to keep a DB *transaction* open during presentation layer rendering. The only sensible way to implement Open Session in View is to complete any transactions *before* view rendering and just keep the underlying Session open, to release locks early.

    Unfortunately, there are quite a few primitive OSIV implementations around, such as filters that execute the entire HTTP request within a JTA transaction. Even the Hibernate team tends to recommend such crude solutions, to avoid "ad-hoc transactions"... a bad tradeoff, IMO.

    And some environments don't even allow to keep the ORM session open outside transactions, due to the lack of explicit resource handling... This in particular applies to the traditional view of a J2EE environment, where ORM sessions are solely managed as part of JTA transactions.

    Interestingly, not all ORM tools require the session to be open for lazy loading: Hibernate and JDO do, but TopLink and OJB don't - lazy loading will work there without active client session as well. Neither does iBATIS SQL Maps, but that's of course a different level of data access API.

    BTW, Spring's OpenSessionInViewFilter / OpenPersistenceManagerInViewFilter keeps the plain session open, with transactions being started and completed in the business layer (as usual), all of them working on the same Session. You guessed that I would mention that :-)

    Juergen
  49. Anti-pattern is right![ Go to top ]

    Just serialize your domain object and pass that to the presentation tier. I'm surprised how many people are afraid to send a domain object to the presentation tier.

    The lack of fear can sometimes be associated to ignorance.
    You mean serializing the whole object tree? Just the root object? How much object tree should be passed on to the client? And don't tell me you have no object tree in your domain, 'cause that means your design is not OO; if that´s the case, this conversation is over. We can as well go back to VB 6.
    The DTO pattern (or Value Object, if you wish) attacks a main issue: decoupling layers (client/domain, domain/persistence, whatever/whatever). As a consecuence of applying the pattern, the layered architecture begins to resemBle a service oriented architecture: the client "sees" objects that offer services. Yes, they are still objects, or components; but the client receives a DTO tree as the resuilts of the requested service nvocation, and those DTOs (usually) are just data holders. Thus, you can make the service retreive the EXACT DTO your client needs, containing ONLY the data it needs. Thats the pretty consecuence; the downsides are there, of course, stale data being the main one.
    Such a service should not be placed in the same component that implements business logic, but in what we call a facade... yes, another pattern.
    That's the beauty of using proven design solutions (a.k.a. design patterns) as tools: you put one on top of the other. The result is your architechture.

    So, rambling about quick and dirty techniques is quite easy, but no deep at all.

    Cheers and happy coding,
    Martin
  50. Anti-pattern is right![ Go to top ]

    And don't tell me you have no object tree in your domain, 'cause that means your design is not OO; if that´s the case, this conversation is over. We can as well go back to VB 6.
    A <100% OO design is no reason to back to VB6. I've tried multiple times to do OO in VB (as much as the tool would allow). What a pain.
    The DTO pattern ... attacks a main issue: decoupling layers ... and those DTOs (usually) are just data holders.

    Funny how you make this statement and the previous in the same post. Do you see the dichotomy in your statements?

    DTOs are not OO (Might as well do VB6 :) ).

    Oh, and if a DTO does anything besides "holding data", it isn't a DTO.
  51. Anti-pattern is right![ Go to top ]

    A <100% OO design is no reason to back to VB6. I've tried multiple times to do OO in VB (as much as the tool would allow). What a pain.

    OK, so we agree on this.
    DTOs are not OO (Might as well do VB6 :) ).

    I wonder why tyou think DTOs are not OO. They are not OO if you don't design them that way. The moment you extend one DTO class from another, you are thinking OO, even if they do not implement any business logic. I bet you did this sometime.
    There's no contradiction between my comments, you just misunderstood both of them, pretty much as you misundertand the DTO pattern.
    Oh, and if a DTO does anything besides "holding data", it isn't a DTO.

    I bet all your DTO's have public attributes; no getters, no setters. And always arrays, of course, God forbid a Collection. THAT would be funny.

    Cheers and happy coding,
    Martin
  52. Anti-pattern is right![ Go to top ]

    DTOs are not OO (Might as well do VB6 :) ).
    I wonder why tyou think DTOs are not OO. They are not OO if you don't design them that way.
    While they do exhibit some OO qualities, they are not OO.
    A quote from this link - http://java.sun.com/docs/books/tutorial/java/concepts/ : "These real-world objects share two characteristics: They all have state and behavior."

    Sometimes we do have to take a step back from OO to solve certain problems. T.O.'s do this.
    The moment you extend one DTO class from another
    Inheritance should be carefully used and should be the least used tenet of OO.
    , you are thinking OO
    Thinking isn't being. I was thinking OO in VB6. Was I doing OO?
    , even if they do not implement any business logic. I bet you did this sometime.
    I do have some objects that look like DTOs - but they need to be refactored.
    There's no contradiction between my comments, you just misunderstood both of them
    Well you said that not having a tree in one's domain means that the design wasn't OO and that "We can as well go back to VB 6". Then you talk about the DTO pattern which seperates state from behaviour. This is not OO either. Definitely not any more OO than not having a tree in your domain.
    pretty much as you misundertand the DTO pattern.
    Not sure why you think I misunderstand the DTO pattern. I understand it quite while. BTW, can you provide a link to the DTO pattern as you have described it (any psuedo official one will do)? The only place I would use the TO pattern is described in this link - http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html
    Oh, and if a DTO does anything besides "holding data", it isn't a DTO.
    I bet all your DTO's have public attributes; no getters, no setters. And always arrays, of course, God forbid a Collection. THAT would be funny.Cheers and happy coding,Martin

    I don't use DTOs or TOs or VOs (although, as I said, you might find things that resembled them). And if I did (see the J2EE link) there is no need for the accessors. Might have them, but not need them.
  53. Anti-pattern is right![ Go to top ]

    While they do exhibit some OO qualities, they are not OO.
    It makes no sense to argue againts this comment; it's quite clear that we will never agree o this.
    Inheritance should be carefully used and should be the least used tenet of OO.
    You sound SCARED of inheritance.
    Thinking isn't being. I was thinking OO in VB6. Was I doing OO?
    Of course not. But you are trying to twist the meaning of my words. If you can implement inheritance, you are in the way of OOness; the fact that the other way around proves something else - this being that VB6 is not OO - does not invalidate my statement. In logic terms: a => b does not imply b => a.
    I do have some objects that look like DTOs - but they need to be refactored.
    I'm not in the least surprised.
    Then you talk about the DTO pattern which seperates state from behaviour.
    This claim, if nothing else, proves that you misunderstand the pattern. Even with DTOs, you still have domain objects with both state and behaviour. You are not "separating" state from behaviour in ANY way.
    BTW, can you provide a link to the DTO pattern as you have described it (any psuedo official one will do)?
    The one you provided is my only source, since I tend to discard what you call "psuedo official ones" unless I'm convinced of their correctness.
    [...]there is no need for the accessors. Might have them, but not need them.
    Well... we don't agree about a single thing. ;)

    Cheers and happy coding,
    Martin
  54. Anti-pattern is right![ Go to top ]

    You sound SCARED of inheritance.
    No. I use it. I just try to do it wisely. The point was that you are using a tenet of OO that is to be used sparingly to support your viewpoint. I am not the only one saying it. Found a bunch of links, but here is one - http://brighton.ncsa.uiuc.edu/~prajlich/T/node14.html
    "... In general, object composition should be favored over inheritance. ..."

    Of course not. But you are trying to twist the meaning of my words.
    No I am not. Whether one chooses not to do something or that he can't does change the fact that he didn't.
    This claim, if nothing else, proves that you misunderstand the pattern. Even with DTOs, you still have domain objects with both state and behaviour. You are not "separating" state from behaviour in ANY way.
    So your DTOs do have methods (not counting accessors) that act upon the "data" they contain?
    The one you provided is my only source, since I tend to discard what you call "psuedo official ones" unless I'm convinced of their correctness.
    That is what I thought. The link doesn't support your position.

    From the link:
    "Context - Application clients need to exchange data with enterprise beans."

    Notice it doesn't talk about seperating the UI from the Domain.

    "The TransferObject is an arbitrary serializable Java object referred to as a Transfer Object. ... Typically, the members in the Transfer Object are defined as public, thus eliminating the need for get and set methods. If some protection is necessary, then the members could be defined as protected or private, and methods are provided to get the values. ... "

    [...]there is no need for the accessors. Might have them, but not need them.
    Well... we don't agree about a single thing.See above quotes. It seems it is not just me that you don't agree with.
  55. Anti-pattern is right![ Go to top ]

    I just try to do it wisely
    "... In general, object composition should be favored over inheritance. ..."

    I just can't beleive you quoted that. We should argue about the validity of that colorful article in another thread, though.
    So your DTOs do have methods (not counting accessors) that act upon the "data" they contain?

    Of course not. They never had "business" behaviour and they never will. Since they never had any, I'd have a really bad time trying to SEPARATE it, wouldn't I? Thus, state is REPLICATED into DTOs... it NOT separated. Quite different.
    "Context - Application clients need to exchange data with enterprise beans."

    You should have payed some attention to this, instead: "Some methods exposed by the business components return data to the client. Often, the client invokes a business object's get methods multiple times until it obtains all the attribute values." And to this: "[...]such remote invocations use the network layer regardless of the proximity of the client to the bean, creating a network overhead." And to this: "Solution: Use a Transfer Object to encapsulate the business data[...]".

    It does not talk about separating UI from domain, but as a professional you certainly could read beyond and understand that if the client (UI or not) by using DTOs no longer "knows" about the domain model, you can very well affirm its "decoupled".

    Oh, and about the accessors, 5 lines after your quote you can find this: "It is a design choice as to whether the Transfer Object's attributes are private and accessed via getters and setters, or all the attributes are made public".

    Thus, it all comes down to design choices, right? Based on your "composition over inheritance" quote and the conversation we had over the last couple days, it's pretty clear to me that your design choices and mine are ruled by different criteria.
    Of course you understand the pattern. You wouldn't be able to discuss it if you didn't; I was just trying to be mean, and apologize for that. But I still don't agree with you.

    Respects,
    Martin
  56. Anti-pattern is right![ Go to top ]

    It does not talk about separating UI from domain, but as a professional you certainly could read beyond and understand that if the client (UI or not) by using DTOs no longer "knows" about the domain model, you can very well affirm its "decoupled".
    True. But the pattern is about network issues, not decoupling. The things you quoted continue to prove my point.
    Oh, and about the accessors, 5 lines after your quote you can find this: "It is a design choice as to whether the Transfer Object's attributes are private and accessed via getters and setters, or all the attributes are made public".
    That is I did "...". It was proving my point that one may or may not use them. I really didn't want to repost the whole page/ :)

    I've never had any problem using the domain model in the UI. (Sometimes I've used Interfaces sometimes I haven't) I did have two projects where we used DTOs (they started it before I took over the project) and VOs. And both were a major pain. Things began to clear up as we removed/stop creating new DTOs/VOs. Maybe our domain model wasn't as good as it could have been but it was much better than struct objects.

    Have fun.
    Mark
  57. Protecting the Domain Model[ Go to top ]

    Ok,
      Did a quick read and have 2 things to add to help "Protect the Domain Model".

    1. Unit testing.
    2. Have an alternate "UI". This can be a as simple as a command line interface. Once you get good at it, thinking about it may be good enough. The unit tests might play this roll too.

    Ok, one more. Have Business objects be Business objects - they should know if they are valid or not.
  58. Protecting the Domain Model[ Go to top ]

    A primitive binding framework might require that all fields coming from the UI (HTTP request or a Swing form) must be stored using anemic setters.

    This one is good. I would like to know what "primitive" is in this context
  59. IMO, we don't have any single solutions for all the problems, something like:
    1. Use DTOs everywhere or
    2. Never use DTOs.

    My solution is something like:
    1. If you are using Hibernate or JDO, use the same POJO domain models everywhere as far as you can. If you are using EntityBean you don't have any choice. You need to have extra POJOs.
    2. Add DTOs where you may need it. DTOs are still POJO anyway but don't use that "DTO" word as the suffix of your POJO. Use something meaningful. Instead of "AddressDTO" you can use something like "AddressVisualization" or so. This makes your "DTO" as the part of your POJO domain model.
    3. Do not repeat yourself. Having a domain model of "Address" and "AdressDTO" which have all the same methods and fields is useless. At the end both of them are POJO anyway...
    4. If you need to send a stucture of objects from your business layer to your presentation layer and don't want to get the "lazy init" error, you can go through the structure and create all the objects you may need. But again use the same POJO domain model and don't create new POJOs.
    5. Last but not least: Use UML to model your domain model and MDA tool like AndroMDA to generate them. Because at the end what we want is to have a "subjective" good design of our domain models, right? Using AndroMDA also allows you to "mark" your domain model (classes) and generate some helper objects automatically (as far as you need them). A lot of things can be done automatically thanks to AndroMDA. This is very useful especially if you have a huge domain model.

    Cheers,
    Lofi.
    EJOSA - OpenUSS
  60. Good post Lofi! Especially #2. I have actually seen a project that had something like PersonDTO and then implemented an interface of IPersonDTO. :)
  61. These are great points, Lofi. Especially I like suggestion # 2. In my blog entry I wrote about the techniques I had in my mind to address issues that arise when not using DTOs. Your list is a great addition to the few ones I had thought of.
  62. Problems with Domain Objects[ Go to top ]

    Lofi, I like some of your comments, but would like to hear your response to some of the issues I have experienced in using domain objects:

    1. In general, I like to have audit fields (such as dateTimeCaptured, userCaptured, etc) in each domain object. As such, I don't like the fact that these are transmitting each time to the web tier.

    2. Also, if Domain Object A has a relationship to Domain Object B, then this would be done through a normal association. However, when this relationship is created through the web tier, it would normally be much easier to just create this relationship through a DTO for Domain Object A, and specify the association to B via B's unique Id, and not have to lookup the object itself.

    Any comments on how these issues can be easily reolved just using Domain Objects and not DTO's.

    Chris
  63. Audit Fields and Association[ Go to top ]

    Hi Chris,

    <chris>
    1. In general, I like to have audit fields (such as dateTimeCaptured, userCaptured, etc) in each domain object. As such, I don't like the fact that these are transmitting each time to the web tier.
    </chris>

    In this case I would take AndroMDA. I just designed a simple "Address" class and let AndroMDA generate an "AddressAudit" class which has the fields I needed. Example:

    UML (source):
    Class Address
    -street
    -number

    AndroMDA generates:
    (1)Java (Business Domain, target):
    Class Address
    -street
    -number
    -auditId

    (2)Java (Audit Domain, target):
    Class AddressAudit
    -dateTimeCaptured
    -userCaptured
    -serverCaptured
    -businessId

    So, I will have 2 different domains, one my "business domain" and one my "audit domain"... Between those classes you will have 1:1 relationship (auditId - businessId). Doing this with AndroMDA is very easy and in your design time you only need to make *one* UML class (source).

    Advantages of this style:
    - separation of concern "Business" and "Audit".
    - no need to send the audit objects back and forth.

    Disadvantage of this style:
    - performance because you need maintain those 1:1
      relationship...

    <chris>
    2. Also, if Domain Object A has a relationship to Domain Object B, then this would be done through a normal association. However, when this relationship is created through the web tier, it would normally be much easier to just create this relationship through a DTO for Domain Object A, and specify the association to B via B's unique Id, and not have to lookup the object itself.
    </chris>

    Yes this correct. But again you just use the POJO domain object for this "state" because domain object is still POJO if you don't use EntityBean. I normally use Use Case diagrams additionally for this purpose to see how should I create the objects with its relationship. Check my article on specification:
    http://www.jaxmagazine.com/itr/online_artikel/psecom,id,671,nodeid,147.html

    Mostly I would do this (like you said):

    Class UserActivity
    -createAWithBId(A a, String id)

    or

    -createBWithAId(B b, String id)

    So you already have one object available, for this you just need the id. For the other object you can create the domain object and pass it through your workflow (activity) object.

    I hope I understand you correctly ;-)

    Cheers,
    Lofi.
  64. I'm on a project now that for 18 months was using TOs (we dropped the "D") exclusively. What we found was that littered all throughout the presentation tier was business logic enforcing the state of the TOs. And as we added a second interface (webservice), we sound we were going to be duplicating a lot of that business logic.

    We're now refactoring to use BusinessObjectcs (i.e. domain objects). These will contain a TO (or subgraph of TOs) and expose methods for working with these. Its not yet as tight and smooth as I'd like it, but our presentationt ier code is getting a LOT simpler and we can now be ensured that oru data will be in a consistent state because its only accessible through a container (the BusinessObject) that enforces the business logic.

    As others have pointed out, there's room for improvement. I'm not sure we need a separation of the data within the BO. Why not just serialize the whole thing? One reason holdinehg us back is that some of the operations we perform on the BO rely on services specific to a tier, so we either need to delegate the BO method to the middle tier, or expose each middle tier service directly so the BO methods can invoke them from the presentation tier.

    In general, I find working with domain objects far better from a design, initial development, and maintinence perspective. Its the actual implementation of a consistent domain object framework that can be tricky to get right.
  65. stupid question[ Go to top ]

    In the session "evolving the architecture", the author mentioned "Maybe some additional UI specific helper classes or model classes are necessary to host the presentation logic that was leaked into the domain classes." How do you differentiate "domain model" and "UI specific model class"? Is there always a clear-cut line between them?
  66. stupid question[ Go to top ]

    How do you differentiate "domain model" and "UI specific model class"? Is there always a clear-cut line between them?

    In a UI specific model class I would allow methods that are related to UI like validation, formatting for display etc. The model here refers to the models in the MVC pattern. Such logic does not belong to the domain classes.
  67. Protecting the Domain Model[ Go to top ]

    To all of you who defend contract driven design and elaborate domain models:

    Why Smart People Defend Bad Ideas
  68. But why is it bad?[ Go to top ]

    You imply that it is bad with your suggestion to read that article, but you have no argument of why it is bad. Care to back that implication up?
  69. But why is it bad?[ Go to top ]

    You imply that it is bad with your suggestion to read that article, but you have no argument of why it is bad. Care to back that implication up?

    Of course,

    Monkey See, Monkey Do

    Dual Persistence Strategies

    Framework Consequences
  70. But why is it bad?[ Go to top ]

    Of course,Monkey See, Monkey Do

    Building frameworks vs. building applications. I tend to build my applications on top of frameworks. Some frameworks I need don't exist. So, rather than hard code the missing framework everywher I need it, I create the framework as decoupled as is reasonable, and build upon it as I do the others.

    My point is that I don't see your point. How does this article support that "protecting the domain model" is bad? Protecting it is a paradigm that can be done while building the application with or without the help of a framework.
    Dual Persistence Strategies

    This simply says don't use DAOs when you can use Hibernate directly. This doesn't touch on "protecting the domain model" at all. In fact, there's nothing that says that the objects Hibernate is getting for you couldn't be those very domain objects.
    Framework Consequences

    This article says, "In my experience, this mindset of defensive programming only hurts projects as you spend more time developing ways to cleanly abstract models/services than simplifying the core competancies of the task at hand."

    However, avoiding tight coupling isn't for the sake of abstraction, its for the sake of maintinence. When your code is more loosely coupled and has higher cohesion, changes you'll be able to make more changes locally without impacting other locations in unforseen way. It doesn't eliminate the possibility, but reduces it.

    Granted, this can be taken to an extreme. Consider the example from your link where an abstract persistence framework is proposed with Hibernate being plugged in behind it, but could be switched out without affecting consumers of the framework. I agree with the assessment that this is very unlikely to occur. But the bigger propblem is having a persistence framework (whether it be abstratc, or direct Hibernate at all)! Persistence is an aspect or cross-cutting concern, not a piece of business functionality the end-user needs to accomplish their goal. Form the perspective of the domain model (which is what this whole big thread is about), the domain objects should take care of persisting there data doing whatever is necesary when the requiremnts say so.
  71. But why is it bad?[ Go to top ]

    I simply take the K.I.S.S approach. I declare everything I can final and opt for composition over larger domain objects in order to promote reusability at multiple levels.

    Keep in mind, the single application developer won't see any advantage to this over persisting heavy domain objects, but I come from a corporate background where the objects you develop must be used in different contexts/applications where marrying logic and state within a single domain object is impractical long term.

    Everyone has their own definitions of domain objects and where the lines are drawn, but from an implementation standpoint, you simply have a set of stateful objects that are representative of a specific table in your DB, they do provide intrinsic behavior and know nothing of any object relationships. The next step up is the concept of application objects (not domain) which delgate state to the perstistent objects and take care of coordinating relationships and behaviors based on specific application needs.

    It's worked super well for us thus far with reusing libraries and layers in multiple applications. Simply put, avoid abstraction and avoid contract driven design-- K.I.S.S and refactor when it's required.