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).
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 follows :
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 allows clients 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 typically accesses 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 names and payroll information.
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 partners placing orders for a particular type of coffee. Rather than returning all of the business partner information or forcing a client to call individual methods for every piece of data, you can create a custom group of DataTransferObject instances and place the group in a DataTransferCollection instance. Figure 16-3 illustrates this alternate scenario.
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 variables or through property accessor and mutator methods.
The sequence of interactions for calling the setDataTransferObject() operation on the BusinessObject instance is, essentially , reversed . The Client instance creates an instance of the DataTransferObject instance and populates it with data. The Client instance then calls the setDataTransferObject(DataTransferObject dto) operation on the BusinessObject instance. The BusinessObject instance is responsible for taking the values from the DataTransferObject instance and inserting them into the values on the BusinessObject instance.
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.