The Data Transfer Object pattern started coming into practice as users of distributed object systems tried to improve performance in their network-based applications. Using Remote Method Invocation (RMI), a typical benchmark observes a substantial increase in time for a method call to complete. This increase is typically from less than a millisecond per method call in a local scenario to around 10
With a little analysis, you will quickly find that the amount of data is not the cause of the performance impact; it is the variability inherent in remote connections combined with the mechanics of communicating across a network. By simply reducing the number of times you place data onto the network and the number of times you do the work to put the data on the network, you can improve the performance of your application. In fact, you can place more data on the network in each call to reduce the number of connections and still recover substantial performance gains.
The Data Transfer patterns work for both retrieving data and changing data on the server. The Data Transfer Object pattern works by having the server-side component developer define common attributes of a business object, or other base type, that clients typically access or change as a
The Data Transfer Collection pattern works by taking some data transfer objects and bundling them into a collection. So, rather than requesting customer summary information for individual customers, you can request customer summary information for all customers. This information gets returned to you in a collection of data transfer object instances.
Often, the Data Transfer patterns are discussed in terms of data retrieval, but they are equally important for updating information. Clients can create and populate the Data Transfer patterns and submit the objects to the server side for updates.
Virtually all distributed systems now use the Data Transfer Object pattern. My first encounter with the pattern was in the Jini environment, but I now see it throughout all business applications that base their environment on object- oriented technologies.
For the value you receive from the Data Transfer patterns, the overall structure is relatively simple. The first, the Data Transfer Object pattern, is simply an additional object created by the BusinessObject instance and consumed by the Client instance, or vice versa. The Data Transfer Collection pattern is simply a first-class collection of the data transfer objects. The following sections show each of these patterns in slightly more depth.
The Business Object pattern makes yet another appearance in this book as the center of the Data Transfer Object pattern: the BusinessObject class. Keep in mind that you can use any of the other base patterns (the Business Object Collection, Business Process, or Asynchronous Business Process pattern) in place of the Business Object pattern. The other classes that participate in the Data Transfer Object pattern are a Client application class and the DataTransferObject class itself (see Figure 16-2).
Figure 16-2:
Structure of the Data Transfer Object pattern
The association between the Client instance and the DataTransferObject instance is a usage or a creation relationship. The association between the DataTransferObject instance and the BusinessObject instance is also a creation or a usage relationship. Neither the Client instance nor the BusinessObject instance contain or aggregate the DataTransferObject ; rather, this object gets created on demand and disappears from scope as necessary (in other words, it is a transient object).
Three classes make up the complete Data Transfer Object pattern:
Client, DataTransferObject
, and
BusinessObject
. The descriptions for the classes are as
DataTransferObject: The DataTransferObject class contains a subset of the data available in a BusinessObject class, but it contains more than a single value from the BusinessObject class. Instances of a DataTransferObject class are transient in nature and are created for the sole purpose of moving data in bulk from a client to a business object, or vice versa. The DataTransferObject class contains no behavioral
methods and, if in Java, typically allows direct access to the data attributes rather than wrapping the data in get/set methods.BusinessObject: The BusinessObject class contains data of interest to a client. This data is typically accessed in groups of properties, giving a relatively consistent pattern of access. Instead of requiring separate methods for accessing
related properties, the BusinessObject class allowsclients to call a single operation, the getDataTransferObject operation. This operation sends the DataTransferObject class that contains the entire collection of related data to the client. Clients can also send a DataTransferObject class to the BusinessObject class for setting data rather than calling separate set methods to change data. The BusinessObject class typically creates a new DataTransferObject class for each client request.Client: The Client class is a client of the BusinessObject class and is usually physically
distant from the BusinessObject class. In scenarios where the client and business object reside in the same process, the value of the DataTransferObject class is not as obvious. The client typicallyaccesses groups of data from the BusinessObject class.
The actual contents of the
DataTransferObject
class will be a set of data from the
BusinessObject
class. There can be more than one
DataTransferObject
class available from a
BusinessObject
class. This scenario is common if there are different types of clients that want different types of information. For example, one client may be interested in simple names from a customer object, and another client may want
The Data Transfer Object pattern can also apply to business object collections. This pattern variation, known as the Data Transfer Collection pattern, returns common attribute groups from a collection of objects. For example, you may want the names of all business
Figure 16-3:
Data Transfer Collection pattern structure
The Data Transfer Collection pattern is extremely useful with large collections where the full transfer of state between a client and a BusinessObject instance would affect bandwidth and processor consumption. The only additional component in this structure is the DataTransferCollection class. This structure contains a collection of DataTransferObject instances. Like the Data Transfer Object pattern, a BusinessObjectCollection instance will create the DataTransferCollection instance and its contents and pass a copy to the Client instance. The other direction is valid as well. A Client instance could create a DataTransferCollection instance containing a set of DataTransferObject instances that the server should change.
There are only a few planned collaborations in the Data Transfer Object pattern. To understand the nature of these collaborations, you must remember that an instance of DataTransferObject is transient in nature. There is no reason to persist a DataTransferObject instance because the live data resides within the BusinessObject instance. The data within the object is the same data that one would expect from calling one or more property accessors on the BusinessObject instance. In the reverse direction, when the Client instance originates a DataTransferObject instance, the properties in the object are the same as what you would expect to be passed on a set of data mutators that reside on the BusinessObject instance.
Figure 16-4 shows a sequence for retrieving data from a
BusinessObject
instance. Rather than calling individual get methods, the
Client
instance calls the
getDataTransferObject()
operation on the
BusinessObject
instance. The
BusinessObject
instance constructs an instance of a new
DataTransferObject
instance and populates it with the appropriate data. Often this data is simply passed to the instance on the constructor, a single
set
method, or by directly populating the individual properties. The
BusinessObject
instance returns this instance to the
Client
instance. The
Client
instance then accesses the data, either through the public instance
Figure 16-4:
Data retrieval sequence for a data transfer object
The sequence of interactions for calling the
setDataTransferObject()
operation on the
BusinessObject
instance is,
The collaborations between the Client instance and the BusinessObject instance are remote operations. Further, when the DataTransferObject instance originates with the BusinessObject instance, the Client instance receives a copy of the object, not a reference to the original. After retrieving the DataTransferObject instance, any changes to the data must be submitted through the setDataTransferObject method to have any effect on the original data.