Avijeet Dash and Satyabrata
Dash
J2EE Applications implement business services by the enterprise java beans
i.e. session beans and entity beans. Every method call to these business service
objects is potentially remote. Such remote invocations use the network layer
regardless the proximity of the client to the beans. Often clients invoke a
business objects get methods multiple times until it obtains all the business
values. Such fine grained data accessor methods causes performance overhead. The
solution Value Object pattern provides is to club such related business
attributes in simple java classes having setters and getters for all such
attributes. Such java objects, known as Value objects or Data objects should be
Serializable, so that they can be transferred over the network. These value
objects are passed by value to the business objects and from business objects.
The clients talk to local copies of such data objects for all data attributes.
Thus the basic key of value objects is to transfer more data in fewer remote
calls and so reducing the overall network overhead arising in case of multiple
round trips in fine grained data access calls.
Thesequence
diagram shows the interactions for a Value
Object pattern
Sample code
Entity Bean class implementing Value List pattern
public class UserBean implements EntityBean { protected String userName; protected String password; protected String firstName; protected String lastName; public UserDetailsVO getUserDetails() { return createUserDetailsVO(); } private UserDetailsDO createUserDetailsVO() { UserDetailsVO userDetails = new UserDetailsVO(); UserDetails.username = this.username; UserDetails.password = this.password; UserDetails.firstName = this.firstName; UserDetails.lastName = this.lastName; } ... //ejb specific methods and business methods }
Value Object Class
public class UserDetailsVO implements Serializable{
protected String userName; protected String password; protected String firstName; protected String lastName; public String getUserName(); public setUserName(String name); public String getPassword(); public setPassword(String password); public String getFirstName(); public setFirstName(String fName); public String getLastName(); public setLastName(String lName); ... }//UserDetailsBean
Updatable value objects
Generally applications have a greater frequency of read transactions than
update transactions. The client requires the data from business tier for
presentation, display and other read-only type processing. Such read-only data
access can be implemented using Data access objects using plain JDBC or using
read-only entity beans. In any of these approaches value objects greatly
simplify the remote data transfer to clients. The value object is also used to
carry the changes required by the client back to the business object.
Such a value object lets the business object like session bean have a simple
interface of having one set method for the complete data object instead of many
set methods. The set methods of the value object can be used for any field level
validations and integrity checks.
However using updatable value objects impacts the design in terms of update
propagation, synchronization and version control.
Typically many clients talk to entity beans or session beans and get their
copy of value object. When one client sends an updatable value object to the
entity bean and the entity bean modifies the data, some clients still hold the
old copy of value objects. It’s not possible to propagate the update to the
stale value objects held by other clients.
When multiple clients tries to update data concurrently synchronization
issues has to be taken care of. The stricter transaction property like
TRANSACTION_SERIALIZED ensures transaction integrity. The isModified pattern
provided a kind of version control to know if the filed has changed or not. Such
issues are taken care of by the containers in application servers.
Entity Beans and Value Objects
One of the most common operations in EJB is "getting" data from
entity beans. Consider a "User" entity bean, which models all the
information of a user of a website. A User has a first name, last name, street
address, telephone number, etc. The problem is that When trying to get this data
from the entity bean, each call to a "getter" (ie: getFirstName(),
getLastName(),...) involves a network round trip, transactional overhead on the
part of the app. server, serialization, etc. Too many queries of this sort will
make your transactions longer and your system less scalable.
The solution to this problem is to have value objects that contain all the
attributes of the User Entity Bean. That is, create a UserDetailsVO that
contains a first name, last name, phone number, etc, as well as getters and
setters.
- Entity beans inheriting from Value objects
To reduce code duplication entity beans can inherit from your details
objects, which will clean up code considerable because you can now move your
attributes and getters/setters out of your entity beans (into the details
objects). This has the disadvantage of making the methods in value objects
to throw RemoteException and the attributes public.
public class UserBean extends UserDetailsBean implements EntityBean {
//ejb specific methods and
business methods
}
- Using dependent value classes under the EJB 2.0 specification. Under EJB
2.0 container-managed persistence, a dependent value class can be mapped to
a subset of columns in a database table. Under this implementation, an
entity bean representing a particular row in the table can maintain, as one
(or more) of its fields, an instance of a dependent value class—a
dependent value object, as it were—to contain a subset of column values.
A dependent value object is a value object that is more tightly coupled
to the entity bean which owns it. Like a value object, it is a
coarse-grained data structure used to access fine-grained data.According to the EJB 2.0 specification, an entity bean using CMP must
provide corresponding accessor (i.e. getXXX) and mutator (i.e. setXXX)
methods for the dependent value object. When the accessor method is called,
the method returns a copy of the dependent value object. When the mutator
method is called with a value object as argument, the values of the value
object are copied into the target dependent value object.
Multiple value objects / composite value objects
Clients usually need various views of the data for different display
requirements and other data processing. The usual approach is to have many value
objects for various views. There is a one-to-many relationship between business
objects and value objects it can produce. Value List Handler is another pattern
that provides lists of value objects. The value object assembler is a pattern
that builds composite value objects from different data sources.
Reference:
http://www.theserverside.com/patterns/thread.jsp?thread_id=79
http://java.sun.com/blueprints/patterns/j2ee_patterns/value_object/index.html
http://developer.java.sun.com/developer/restricted/patterns/ValueObject.html
Core J2EE Patterns, Deepak Alur, John Crupi, Dan Malks http://developer.java.sun.com/developer/technicalArticles/J2EE/patterns/