Rewrite of the Value Object pattern

Discussions

J2EE patterns: Rewrite of the Value Object pattern

  1. Rewrite of the Value Object pattern (29 messages)

    The Value Object pattern was originally created to respond to a performance issue with clients communicating with enterprise beans. The issue is that it’s more efficient to pass one argument with many component fields than to pass the fields individually. Text to the pattern on the Javasoft site is: http://java.sun.com/blueprints/corej2eepatterns/Patterns/TransferObject.html

    On this site and in many other contexts, I’ve seen many extensions and variants of this pattern applied in different contexts. For example, I’ve seen this pattern applied to XML/Object mapping problems, Schema/Object mapping problems, and many more. The trend seems to be to extend the basic idea of combining related data items into a single object and applying it to contexts that have different technical specifics.

    I assert that this trend is a symptom. The root issue is that we’ve defined the “problem” too narrowly in the Value Object pattern. There are more uses to the value object concept than clients communicating with enterprise beans.

    I think we should go the other direction. Let’s rewrite the Value Object pattern in much broader terms, that could conceivably allow applying the pattern to different contexts.

    I’ve sketched an idea for rewriting the value object pattern in broader terms and would like feedback. Here goes…

    Problem: Objects need to exchange composite data with other objects. Composite data is a group of data items that logically belong together (e.g. data about a customer, account, item, etc.). Sometimes there are business rules surrounding specific values some of the component data items can have. Some technologies (e.g. EJB) have performance issues with exchanging large numbers of component data items.
     
    Context: Some composite data items, particularly in business applications, have a long list of related data items. Treating these items individually leads to extremely verbose code and significant change when one of the component data items is changed or added. Furthermore, it isn't clear what objects are responsible for enforcing business rules regarding what values these data items are allowed to have.
     
    Solution: Combine these data items into a single object. Make this object responsible for enforcing the business rules about what values component data items can contain.

    Example: CustomerVO contains a social security number, first name, last name, street address, city, state, zip, and email address.

    CustomerVO enforces the business rule that social security number is required and all fields are optional. It enforces the rule that state is one of fifty two letter abbreviations. It enforces the rule that zip codes are numeric and have 5 digits (or 9). It enforces the rules regarding valid email address syntax.

    It implements Serializable so that it can be used with enterprise beans. Factories can easily be constructed to translate CustomerVO to and from XML format or read/write it from a database. Value objects can identified using object oriented design concepts so that they are useful for more than just one EJB method call type.
     
    Consequences: Adding, changing, or deleting a component data item is much easier affecting far fewer objects. Business rules regarding allowed values for component objects are easier to identify and maintain. Additionally, technical features, such as making these objects Serializable for use with enterprise beans, are very easy to implement.

    Threaded Messages (29)

  2. What is the big difference?[ Go to top ]

    Hi,

    First let me be sure I have understood you correctly. You mean that the value object should contain business logic, so that you can save network traffic by not sending invalid value objects to the ejb's? To me that sounds like simple client side validation instead of server side validation. Not that there is anything wrong with that. But is there a need to rewrite a pattern to do that? I mean, after all patterns are only ideas, not strict you-must-do-it-like-this-or-die laws. If a pattern doesn't solve your problem as it is, modify it till it does. That's what the GOF guys says too.


    Kind Regards,
    Jakob Jenkov
    www.jenkov.com
  3. Re: What is the big difference?[ Go to top ]

    You mean that the value object should contain business logic, so that you can >>save network traffic by not sending invalid value objects to the ejb's?


    Value objects should contain only the business logic needed to guarantee the integrity of the object content and no more. In most applications, this would be a small percentage of the business logic present in the application.

    The value object concept is useful in many more situations than clients communicating with EJBs. Limiting the value object concept to that narrow of a problem is very limiting. I see the concept as having potential in any type of application. I also see opportunities for consolidating the value objects you do have.

    For example, consider a store type of application. One of the most frequent constructs that would be used, read, written, and displayed in an application like that would be information from an individual item available for purchase. I'm proposing that instead of having numerous value objects for our many calls that involve item data.

    Using this expanded form of the value object pattern, declare one ItemVO object with all the fields the application needs. Make it serializable so that it can be communicated to JSPs and Servlets in the presentation tier. The portions of your application that physically read/write item data from the database (be they entity beans, hibernate DAOs, native JDBC DAOs, etc.) use ItemVOs in their method arguments too. Your session beans that communicate use them as well.

    Furthermore, instead of having to place rules that validate that the fields in ItemVO have valid values in your persistence layer, your bean layer, and your presentation layer, put these rules close to where the values are in ItemVO. You would not want to place validation rules in the VO that required database lookups because those resources might not exist in remote containers.

    I hope this is clearer than the original. Thanks for taking the time to respond.

    Derek Ashmore
  4. I understand what you mean. Still, I can see a few minuses with changing the whole pattern:

    The solution is fine if, like you said, validation doesn't require
    database lookup. If it does, you will have to split validation in two.
    One part doing client side (VO-side) validation, and one part doing
    database validation (server-side).

    Personally I would prefer keeping my validation in one spot. Also, the
    VO object validation you are talking about, could also have been achived
    with validation on the form fields where you type in the values.

    I fully understand what you mean, and client side validation can be really useful sometimes. Im only questioning whether the VO pattern should be rewritten to reflect client side validation possibilities...

    Kind Regards,
    Jakob Jenkov
    www.jenkov.com
  5. It sounds like your trepidation about the idea centers around the business logic validation piece.

    If the suggestion about incorporating limited business validation logic in the value object were *not* present. If the idea was simply to amend the value object pattern to verbage that allowed VOs to be used in any tier, not just for communication between clients and enterprise beans, would that make you feel more at ease? Would the what remains of the idea be valuable or so small that it's not relevant?

    Thanks for a most interesting discussion...

    Derek C. Ashmore
  6. Hi Derek,

    Im not sure I understand your last commment. Let me see if I get it right:

    You suggest that VO's can be used to communicate between any two layers in the application, not just between client and server (EJB's). The original reason to have VO's was to save network traffic, so if there is no network communication between two layers, is there any reason to use value objects? Can't you just use the original classes?

    Having said that, I must add that I am currently working on a project where we are using request data objects (DO's) and response data objects, which are very similar to value objects (aren't value objects also called data transfer objects, or data objects?). We are not using EJB, but we still use these request and response value objects to communicate between the frontend (struts) and the backend.

    So yes, it could be useful, and it could be added to the value object pattern no doubt. I was just trying to say that you can always base your code on a pattern, then add the features you need. I think the value object pattern is good enough the way it is. It doesn't take so much fantasy to add VO-validation if it helps you, even if it is not described in the pattern. But it could be mentioned somewhere as a variation on the pattern. That would be nice I think.
  7. Re: What is the big difference?[ Go to top ]

    Check this discussion for User Input Validation:
    http://www.theserverside.com/discussion/thread.jsp?thread_id=21527

    Lofi.
  8. Its been a while since I've looked at the value object pattern (on Sun's web site). I just read it again and something strikes me as strange.

    The first time I applied the VO pattern was not necessarily to save network overhead but container overhead in dealing with many EJBs (maybe this is the same as network overhead?). We wanted access to many objects. However, to create many EJBs is generally to be avoided because of the container overhead, particularly with entity beans.

    For example, we could have a student entity bean. To create a list of students in one school, we could have a student.findBy( school ) method that would return a Collection of student entity beans. This would result in many EJBs being created in the container.

    When generally use VOs in situations like this to drastically cut down on the number EJBs. For example, we may have a school entity bean that has a getAllStudents() method that returns a collection of student value objects. The difference is that the student VOs are not EJBs but POJOs (which are Serializable).

    I guess I am questioning either my understanding of the VO pattern or perhaps that the VO pattern is important for other reasons than reducing network overhead due to remote interfaces?
  9. "Recap:
    1. You write your domain objects.
    2. You access your domain objects in the client application directly (much as you would do with a simple non-distributed MVC servlet application)
    3. Err.. that's it. The optimisation of network traffic is handled by the framework.
    "

    But that only works if domain objects map 1:1 to the data sets that client queries require. IME this largely not true for any non-trivial system unless you have a model will alot of duplication and redundency which of course causes is own set of problems). The whole point of DTOs is to "assemble" information from multiple domain objects as well as to aggregate multiple items from the same domain object.

    Paul C.
  10. Rewrite of the Value Object pattern[ Go to top ]

    Solution: Combine these data items into a single object. Make this object responsible for enforcing the business rules about what values component data items can contain.


    I think you should add the Value Object Factory to your solution. IMO a VO factory is the logic place to put business rules validations rather than in the VO itself.
  11. VO or BO[ Go to top ]

    Hi,
    as far as i think, you mean that business logic should come into VO for server side validations. What i suggest is, let the VO remain for data transfer and minimizing network traffic. Let's use Business Objects(BO) for this.

    In BOs, we can plug the business logic, pass the VO to that and validate whatever we want to, like is social security number there in the VO and if so, is it valid? If it is not there, the Business Rules plug-in class will throw an exception and hence not call the Entity bean.

    Prash
  12. Granularity of VO[ Go to top ]

    I've always felt that the Value Object should represent a business entity in a **particular logical (business-specific) state** rather a grab bag of all attributes.

    As an example, I think you want to avoid graphing and passing an entire (Corrections is my field) Offender VO ; rather, say, an _IntakeOffender or a _pastEarlyReleaseDateOffender.

    Unfortunately, in practice, I've seen the use of this pattern dismissed out-of-hand cuz' a VA is "too large"...it's a matter of well-thought out design and planning, folks...

    Michael Dean
  13. Re: Granularity of VO[ Go to top ]

    Thanks for taking the time to reply...

    In the example you site, have you thought about having a base "OffenderVO" that contains all the attributes that are common to offenders in all "states" (used in the logical sense, not the geographical) and then extending that to "IntakeOffenderVO" and "EarlyReleaseOffenderVO" and so on?

    Do you use your VOs for more than just communicating between clients and enterpise beans? -- just curious.
  14. Re Rewrite of the Value Object pattern[ Go to top ]

    hi

    The original reason of saving remote calls of DTOs-VOs pattern is actually minor importance and really narrow minded.

    The main reason for DTOs-VOs is to provide a container mechanism to pass data betweet presentation layer and the service layer which deal with the
    domain-model layer. Thus DTOs-VOs in combination with Business Delegate and Session facade(both form the service layer), remove coupling-dependency between the presentation and the domain layers, giving all the benefits of abstraction-encapsulation.

    Hence DTOs-VOs are really needed if you have a multi layer architecture,
    Presentation <-> Service <-> Domain. DTOs are passed between the presentation and service layers.
  15. I agree, that is the essence of the VO-FTO[ Go to top ]

    I agree, the DTO-VO pattern really serves two purposes:

    1) eliminate network chattiness when requesting data between client and business tier in the case of EJBs; and

    2) establish decoupling between the presentation (i.e. a client) and the business tier. The client should not have to deal with the complexity of working with a reference to an object in the domain layer. Passing a VO object back and forth eliminates the coupling.

    - Jeff
  16. I agree, the DTO-VO pattern really serves two purposes:

    >
    > 1) eliminate network chattiness when requesting data between client and business tier in the case of EJBs; and

    If you're domain objects aren't strongly coupled to a specific physical location then you don't have this problem. (eg distributed cache)

    >
    > 2) establish decoupling between the presentation (i.e. a client) and the business tier. The client should not have to deal with the complexity of working with a reference to an object in the domain layer. Passing a VO object back and forth eliminates the coupling.
    >
    You can never remove dependencies between the presentation layer and the domain layer otherwise you would never know what to display. If you change the length of the customer "name" field on the domain object, you still have to change the length of the corresponding text box on the web-page. With VOs you're just indirecting the dependency through another layer of objects. It's still there. If you're not using a mediator (a la gang of four) ie a value object factory then you've gained nothing and added a lot of complexity. (Two sets of objects to maintain etc.) In most cases people have a 1-1 relation between VOs and domain objects - all they've got is more complexity.

    Why is a) less complex than b) ? :

    a)
    webpage.nameField = CustomerValueObject.name;
    webpage.ageField = CustomerValueObject.age;
    webpage.addressField = CustomerValueObject.address;

    b)
    webpage.nameField = CustomerDomainObject.name;
    webpage.ageField = CustomerDomainObject.age;
    webpage.addressField = CustomerDomainObject.address;

    Answer: It isn't, in terms of what the webpage does there are exactly the same number of dependencies. But in terms of the system as a whole a) is more complex since you have to maintain a whole new set of objects.

    I don't think people would suggest using value objects if their system wasn't distributed.

    It seems to me value objects are just a hangover to the fact that people seem to insist their domain objects live only in one physical location (eg in their ejb container)

    One other thing against value objects is duplication of code. How many times have you seen a piece of business logic duplicated in the VO since it's required on the presentation tier, and a network call would be too expensive?
  17. I agree!!![ Go to top ]

    Yup Tim,

    That was kinda the point I was trying to make earlier in this thread. But I must say, in the case that the domain objects are EJB Entity Beans, version a) as you described them above, will only have one network call to get the value bean, whereas version b) has a network call for each property accessed in the domain object.


    Second, VO's can actually be a way of simplifying an interface for the user. Say a domain object is complex with lots of methods on, and all I need to do with a certain action is to change one-two fields. Then using a request VO with only the fields to change instead of the domain object can feel simplified.

    Personally, I'd prefer the domain object though. The above approach is used on my current project, and whenever I have to a backend/business logic/domain object request from the front end, I have different request VO's and also get different response VO's. Not too elegant. Every request I have to look at a new class to find out what fields to set/read.
  18. I agree!!![ Go to top ]

    Hi Jakob-

    > That was kinda the point I was trying to make earlier in this thread. But I must say, in the case that the domain objects are EJB Entity Beans, version a) as you described them above, will only have one network call to get the value bean, whereas version b) has a network call for each property accessed in the domain object.
    >

    Not necessarily so. It's possible to implement preloading strategies such that the number of network calls when accessing the domain objects directly from the client is no more that the number of network calls when receiving the data via Data Transfer Objects.
    For instance, say I'm executing a use case on the client. I know that in this use case I require various fields from objects A, B and C. It's possible to preload this data into local copies of the objects at the beginning of the use case in one network call. All this can be done transparently by a framework.


    >
    > Second, VO's can actually be a way of simplifying an interface for the user. Say a domain object is complex with lots of methods on, and all I need to do with a certain action is to change one-two fields. Then using a request VO with only the fields to change instead of the domain object can feel simplified.

    What you're suggesting is the facade pattern - you can have a facade without using DTOs. For instance your facade can provide a simple interface to a set of local domain objects. Giving you all the advantages of using a facade but without using DTOs.
  19. Hmm...[ Go to top ]

    Hi Tim,

    Do you disagree that a call to an EJB, unless local, requires network traffic? Meaning if I call an entity beans .getAddress(), .getCity(), .getCountry(), it will require an RMI call, right? (unless a local bean). I believe this is true no matter if the entity bean has preloaded the domain object into a local copy, and returning the values from that local copy. The client still needs RMI just to call the .getSomething().

    Maybe what I was talking about was a variation of the facade pattern. Maybe not. Was I was saying was just that if a domain object is carried through a long series of components from the client to the deepest backend service, a change in the domain object might affect the code in all these layers using the domain object. By using a set of VO's (1 for requests, and 1 for response) each layer will be completely decoupled theoretically. Practically a domain object change may dictates changes in many of these sets of VO's, and thus the VO's won't really be of much use, like you set in your first post.

    Anyways, I think we pretty much agree on this topic, I think we are just misunderstanding each other a little :-) I too believe more in just exposing the domain objects to the client, UNLESS we are talking about an API that some external customer might be using to access services in my company. Then I'd make sure that any features of the domain object that customer were using, were properly shielded away from him, so he could only do the changes he had the rights to do.
  20. Hmm...[ Go to top ]

    Jakob-

    > Hi Tim,
    >
    > Do you disagree that a call to an EJB, unless local, requires network traffic? Meaning if I call an entity beans .getAddress(), .getCity(), .getCountry(), it will require an RMI call, right? (unless a local bean). I believe this is true no matter if the entity bean has preloaded the domain object into a local copy, and returning the values from that local copy. The client still needs RMI just to call the .getSomething().
    >

    Sure, if it's an EJB. But who said it had to be an EJB?
    What I'm suggesting is that the domain objects are POJOs (probably using some OR tool eg. hibernate to persist on the server side). The POJOs have no dependency on any physical location.
    The client (eg web tier) accesses a local copy of the POJOs, plus it also has access to any service logic (since that has been written with no location dependencies too).
    For any particular use case you pretty much know which objects are going to be accessed so these can be preloaded at the beginning of the use case.
    Bottom line is you get all the advantages of using DTOs (ie reducing network chattiness) without any of the overhead of DTOs (ie extra layer of classes to maintain).
    In detail:
    1. Beginning of use case. Data that will be used in use case is loaded over network from ejb server and used to populate local copy of the objects used in the use case.
    2. Objects are read/written to perform use case.
    3. End of use case. Transaction commits. Changes are transferred over network back to ejb server and "master" model is updated.
    All the to and fro'ing across the network is hidden from the application developer by the framework. So the app developer just codes against the same domain objects and service classes. Irrespective of whether it's on the server or client side.


    > Anyways, I think we pretty much agree on this topic, I think we are just misunderstanding each other a little :-) I too believe more in just exposing the domain objects to the client, UNLESS we are talking about an API that some external customer might be using to access services in my company. Then I'd make sure that any features of the domain object that customer were using, were properly shielded away from him, so he could only do the changes he had the rights to do.

    I agree with you here. Exposing the entire domain graph would not be acceptable in a lot of cases. Having said that, nothing's stopping you writing a facade for those customers that only exposes the objects they are entitled to access. (Still without using DTOs)
  21. Glad to see this documented[ Go to top ]

    Independent of seeing this pattern posted, I have recently developed two different systems (at two different companies) using this pattern. The VO's (or data transfer objects, as I think Fowler calls them) are actually real domain objects. The clients (a web tier client and a swing client) both used a generic server (built around hibernate, in this case) to send and receive objects. The clients manipulated the domain objects directly. This meant no writing duplicate data transfer object, no writing mappings to/from domain objects. Plus I refactored to this solution and deleted over half of the classes in both application. I have to say that the resulting application is quicker and I am much more agile (no duplicate code!) with the apps using this pattern.

    I can see this getting applied to EJBs..why should EJBs produce plain old data transfer objects for their clients? They can just create business objects and they can be passed around server to client to server. In this way, EJB's take on more of being an object/relational tool.

    Good work...
  22. Hmm...[ Go to top ]

    Sure, if it's an EJB. But who said it had to be an EJB?


    Uh, I believe Jakob did. That was the point he was trying to make.

    > In detail:
    > 1. Beginning of use case. Data that will be used in use case is loaded over network from ejb server and used to populate local copy of the objects used in the use case.
    > 2. Objects are read/written to perform use case.
    > 3. End of use case. Transaction commits. Changes are transferred over network back to ejb server and "master" model is updated.

    Okay, you've just described how VOs/DTOs work. You populate it with data, you send it to your client, you send it back to update the persistent layer. Whether you have *extra* complexity of entity beans or not is irrelevant. You're still passing data from one layer to another.
  23. Hmm...[ Go to top ]


    > Okay, you've just described how VOs/DTOs work. You populate it with data, you send it to your client, you send it back to update the persistent layer. Whether you have *extra* complexity of entity beans or not is irrelevant. You're still passing data from one layer to another.

    Greg - with respect, I think you're missing the point I made. What I'm suggesting is to retain all the advantages of using DTOs (ie minimising network chat) but without ever having to write or maintain a DTO.
  24. Hmm...[ Go to top ]

    Greg - with respect, I think you're missing the point I made. What I'm

    > suggesting is to retain all the advantages of using DTOs (ie minimising
    > network chat) but without ever having to write or maintain a DTO.

    But, I think what you're actually doing is combining the two concepts of a persistent object and a DTO. It seems like you're not necessarily bypassing the maintenance of a DTO. Instead, it seems like you're simply combining it with a persitent object. As if you've turned your persistent object into a DTO. Of course, there's absolutely nothing wrong with that. I've seen many good systems built that way. The only thing you *might* lose is the RMI capabilities of EJB. But who really uses that anyway?

    I guess what I'm saying is that you shouldn't say you're not using DTOs when it looks like you actually are. In fact, you might be doing alot of what the original post is talking about as far as binding business rules to the DTO. It looks like you are just looking at it from the other direction.

    -----
     Greg
  25. Hmm...[ Go to top ]

    It seems like you're not necessarily bypassing the maintenance of a DTO.


    In what way is it not bypassing the maintenance of the DTO?

    > Instead, it seems like you're simply combining it with a persitent object.

    Am I? Please show me where.


    Recap:
    1. You write your domain objects.
    2. You access your domain objects in the client application directly (much as you would do with a simple non-distributed MVC servlet application)
    3. Err.. that's it. The optimisation of network traffic is handled by the framework.

    Ie No DTOs to maintain.

    Bottom line is you have one less layer of objects (whatever you want to call them) to deal with than in a "conventional" J2EE distributed application.

    The name you give those objects is largely irrelevant to the crux of the argument.
  26. Difference DTO, EB, Domain Object[ Go to top ]

    The difference:

    1. Servlet -> DTO (POJO) -> Stateless SessionBean -> DTO (POJO) -> EntityBean. In this case "EntityBean" is your domain object and not the DTO. DTO is just purely the Data Transfer Object.

    2. Servlet -> DomainObject/DTO (POJO) -> Stateless SessionBean -> DomainObject/DTO (POJO). In this case "POJO" is your domain object and at the same time the "POJO" is also your DTO.

    Check EJOSA Template http://ejosa.sourceforge.net to see the difference...

    Hope this helps!
    Lofi.
  27. Example: CustomerVO contains a social security number, first name, last name, street address, city, state, zip, and email address.

    >
    > CustomerVO enforces the business rule that social security number is required and all fields are optional. It enforces the rule that state is one of fifty two letter abbreviations. It enforces the rule that zip codes are numeric and have 5 digits (or 9). It enforces the rules regarding valid email address syntax.


    What if, insted of "duplicating" the business rule at vO layer you just make you Business Object having all attributes self descriptive in terms of constraints.

    for each field you have a descrition (uniqueness, length, string format, ...)

    when creating your VO you still use this description (and it can still be valid if the VO is build from multiples BOs).

    The main advantage is that from server to GUI/Client you have the pure description of your enties, and you can decide at each layer how to use it:
    - at GUI level you can use that to format your TextField
    - at VO level you can perform cost-less like length, string format, ... number min | max value, ...
    - at BO level you perform all the test so that you can garantee your object integrity

    code to perfrom controls can be generic and based only on the description.
  28. Rewrite of the Value Object pattern[ Go to top ]

    Value Objects or better Data Transfer Objects are not
    supposed to validate. That's the Idea of the Value Object Approach.

    They are merely supposed to be carriers of data and not
    have the overhead of Business Objects.

    Assume we do as you said and implement basic validation functionality.
    Where would you get the range of possible values from? The client cannot
    load data from the database directly, neither read any server side configuration
    directly. It would require a service (server-side) that allows the client
    to load the range (possibly on start-up).
    Well, you might as well do the validation on the server and use the DTO
    Pattern as is. Also think about the Business Object J2EE Pattern.

    However, I have seen that "Data-On-Demand" strategies with proxy abilities
    was implemented and implementations where Swing GUIs load required data on
    demand basing everything on Value objects.

    In a list view you would possible see the data gathered from the value objects
    (short) and if you double click on an item in the list view, you would
    obtain the detail information. On Mouse Over Event, you might preload the
    data or even before then! However, this is a specialised case of proxy
    functionality, which might be useful to Swing developers or those developing
    GUI Frameworks.
  29. DTO and Business logic: my approach[ Go to top ]

    Value Objects or better Data Transfer Objects are not
    supposed to validate. That's the Idea of the Value Object Approach.

    They are merely supposed to be carriers of data and not
    have the overhead of Business Objects.

    Assume we do as you said and implement basic validation functionality.
    Where would you get the range of possible values from? The client cannot
    load data from the database directly, neither read any server side configuration
    directly. It would require a service (server-side) that allows the client
    to load the range (possibly on start-up).
    Well, you might as well do the validation on the server and use the DTO
    Pattern as is. Also think about the Business Object J2EE Pattern.

    However, I have seen that "Data-On-Demand" strategies with proxy abilities
    was implemented and implementations where Swing GUIs load required data on
    demand basing everything on Value objects.

    In a list view you would possible see the data gathered from the value objects
    (short) and if you double click on an item in the list view, you would
    obtain the detail information. On Mouse Over Event, you might preload the
    data or even before then! However, this is a specialised case of proxy
    functionality, which might be useful to Swing developers or those developing
    GUI Frameworks.
    There are many points of view here, and most have merit. I would like to describe what I am doing right now. It is in a C# project, but it is language/platform neutral.

    After coming off a J2EE/Struts project that got railroaded into a really twisted use of value objects, I figured I'd try moving back toward an OOD point of view. With some judicious proection level use, I think I combined the best of both worlds here. Basically, I've been doing something similar to what the author suggests for months, and it works well on this project.

    We have our basic domain objects, things like quote, employer group, employee, etc. These classes act as floating domain objects, such that some functionality is available to the client, while the rest is restricted to the server. C# has the "internal" keyword, which works a bit like Java's protected keyword, but at the "assembly" (jar) level. I use a business facade in the server assembly, which the client can see, and it passes commands to the domain object. This gives us something closer to a true object (rather than a module that takes structures as input, which a pure VO pattern resembles).

    Example:
    bool QuoteService.SaveQuote(QuoteVO qvo) {
      if (qvo.IsValidAtServer()) {
        return qvo.Save();
      } else {
        return false;
      }
    }

    This is a facade interface that would be called from the client. qvo.Save() is not visible to the client, but is visible to the facade. This facade could easilly become a web service interface. There is a QuoteVO.getXML() method that could be used to produce input to that service rather easilly. The client could call qvo.IsValid(), which would validate the input at a sanity-check level.

    What do you think?

    David
  30. Generalizing DTO/VO[ Go to top ]

    I've often found it useful to generalize DTO/VO to cover any exchange between the presentation layer and the service layer, whether or not they are in the same process.

    This has the following advantages:
    - by returning DTOs rather than domain objects, the service layer APIs clearly document what data is available to the presentation layer or client. Otherwise, if lazy loading is in effect, obj.getFoo() might behave differently whether obj was returned from serviceA() or serviceB(), or whether obj was retrieved from request or session scope.

    - DTOs can often be used as the basis for Struts form beans. Form beans are essentially DTOs anyway: HTTP POSTs are like remote method calls, and form beans are the arguments.

    - All layers are remoting-agnostic. You can expose POJO services over SOAP simply by registering it with Axis or some other SOAP engine. Everything works equally well in-process (and without EJB overhead).

    - Assuming your DTOs and DB schema/mapping are generated with XDoclet, you only have to touch two files to add a new field to an existing class: the domain object itself and the template/JSP used to display it.