Transfer Object Assembler Pattern in Java

Use a Transfer Object Assembler to build an application model as a composite Transfer Object. The Transfer Object Assembler aggregates multiple Transfer Objects from various business components and services and returns it to the client.
This pattern is divided into a number of sections for simplicity like a problem, forces, solution, class diagram, sequence diagram etc.
Table of contents
Problem
Forces
Solution
Structure - Class Diagram, Sequence Diagram
Participants and Responsibilities
Implementation
Consequences
Applicability
References

Problem

(Problem section describes the design issues faced by the developer)
You want to obtain an application model that aggregates transfer objects from several business components.

Forces

(This section describes Lists the reasons and motivations that affect the problem and the solution. The list of forces highlights the reasons why one might choose to use the pattern and provides a justification for using the pattern)
  • You want to encapsulate business logic in a centralized manner and prevent implementing it in the client.
  • You want to minimize the network calls to remote objects when building a data representation of the business-tier object model.
  • You want to create a complex model to hand over to the client for presentation purposes.
  • You want the clients to be independent of the complexity of model implementation, and you want to reduce coupling between the client and the business components.

Solution

(Here solution section describes the solution approach briefly and the solution elements in detail)
Use a Transfer Object Assembler to build an application model as a composite Transfer Object. The Transfer Object Assembler aggregates multiple Transfer Objects from various business components and services and returns it to the client.

Structure

Let's use UML class diagram to show the basic structure of the solution and the UML Sequence diagram in this section present the dynamic mechanisms of the solution. 
Below is the class diagram representing the relationships for the Transfer Object Assembler Pattern.

Class diagram

Sequence Diagram

Participants and Responsibilities

Client - Client invokes the TransferObjectAssembler to obtain the application model data. The Client can be a component of the presentation tier or can be a Session Façade that provides the remote access layer for the clients accessing the TransferObjectAssembler.
TransferObjectAssembler - The TransferObjectAssembler is the main class of this pattern. The TransferObjectAssembler constructs a new composite transfer object based on the requirements of the application when the client requests the application model data.
ApplicationModel - The ApplicationModel object is a composite Transfer Object that is constructed by the TransferObjectAssembler and returned to the Client.
BusinessObject - BusinessObject represents a Business Object that provides Transfer Objects to the TransferObjectAssembler to assemble the ApplicationModel.
SessionFacade - The SessionFacade represents a Session Facade that provides part of the data required to construct the ApplicationModel transfer object.
DataAccessObject - DataAccessObject represents a Data Access Object, used when the TransferObjectAssembler needs to obtain data directly from the persistent store.
Service - The Service is any arbitrary service object including an Application Service in the business tier that provides the data required to construct the ApplicationModel object.

Implementation

(This section includes source code implementations and code listings for the patterns).
Implementing the Transfer Object Assembler
Consider a project management application where a number of business-tier components define the complex model. Suppose a client wants to obtain the model
data composed of data from various business objects, such as:
  • Project information from the Project component
  • Project manager information from the ProjectManager component
  • List of project tasks from the Project component
  • Resource information from the Resource component.
Step 1: Create Composite Transfer Object Class
A Transfer Object Assembler pattern can be implemented to assemble this composite transfer object.
public class ProjectDetailsData {
    private ProjectTO projectData;
    private ProjectManagerTO projectManagerData;
    private Collection < TaskResourceTO > listOfTasks;

    public ProjectDetailsData(ProjectTO projectData, ProjectManagerTO projectManagerData,
        Collection < TaskResourceTO > listOfTasks) {
        super();
        this.projectData = projectData;
        this.projectManagerData = projectManagerData;
        this.listOfTasks = listOfTasks;
    }
}
The list of tasks in the ProjectDetailsData is a collection of TaskResourceTO objects. The TaskResourceTO is a combination of TaskTO and ResourceTO.
Step 2: Create ResourceTOtaskTO , ProjectTO and ProjectManagerTO transfer object classes.
public class ResourceTO {
    private String resourceId;
    private String resourceName;
    private String resourceEmail;
    public String getResourceId() {
        return resourceId;
    }
    public void setResourceId(String resourceId) {
        this.resourceId = resourceId;
    }
    public String getResourceName() {
        return resourceName;
    }
    public void setResourceName(String resourceName) {
        this.resourceName = resourceName;
    }
    public String getResourceEmail() {
        return resourceEmail;
    }
    public void setResourceEmail(String resourceEmail) {
        this.resourceEmail = resourceEmail;
    }
}
public class TaskTO {
 private String projectId;
 private String taskId;
 private String name;
 private String description;
 private Date startDate;
 private Date endDate;
 private String assignedResourceId;
 public String getProjectId() {
  return projectId;
 }
 public void setProjectId(String projectId) {
  this.projectId = projectId;
 }
 public String getTaskId() {
  return taskId;
 }
 public void setTaskId(String taskId) {
  this.taskId = taskId;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getDescription() {
  return description;
 }
 public void setDescription(String description) {
  this.description = description;
 }
 public Date getStartDate() {
  return startDate;
 }
 public void setStartDate(Date startDate) {
  this.startDate = startDate;
 }
 public Date getEndDate() {
  return endDate;
 }
 public void setEndDate(Date endDate) {
  this.endDate = endDate;
 }
 public String getAssignedResourceId() {
  return assignedResourceId;
 }
 public void setAssignedResourceId(String assignedResourceId) {
  this.assignedResourceId = assignedResourceId;
 }
}
public class TaskResourceTO {
    private String projectId;
    private String taskId;
    private String name;
    private String description;
    private Date startDate;
    private Date endDate;
    private TaskResourceTO assignedResource;
    public String getProjectId() {
        return projectId;
    }
    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }
    public String getTaskId() {
        return taskId;
    }
    public void setTaskId(String taskId) {
        this.taskId = taskId;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getDescription() {
        return description;
    }
    public void setDescription(String description) {
        this.description = description;
    }
    public Date getStartDate() {
        return startDate;
    }
    public void setStartDate(Date startDate) {
        this.startDate = startDate;
    }
    public Date getEndDate() {
        return endDate;
    }
    public void setEndDate(Date endDate) {
        this.endDate = endDate;
    }
    public TaskResourceTO getAssignedResource() {
        return assignedResource;
    }
    public void setAssignedResource(TaskResourceTO assignedResource) {
        this.assignedResource = assignedResource;
    }
}
public class ProjectManagerTO {

    private String name;
    private String address;
    private String projects;
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getAddress() {
        return address;
    }
    public void setAddress(String address) {
        this.address = address;
    }
    public String getProjects() {
        return projects;
    }
    public void setProjects(String projects) {
        this.projects = projects;
    }

}
public class ProjectTO {

    private String projectId;
    private String projectName;
    private String projectDesc;
    public String getProjectId() {
        return projectId;
    }
    public void setProjectId(String projectId) {
        this.projectId = projectId;
    }
    public String getProjectName() {
        return projectName;
    }
    public void setProjectName(String projectName) {
        this.projectName = projectName;
    }
    public String getProjectDesc() {
        return projectDesc;
    }
    public void setProjectDesc(String projectDesc) {
        this.projectDesc = projectDesc;
    }
}
Step 3: Implementing the Transfer Object Assembler.
The ProjectDetailsAssembler class that assembles the ProjectDetailsData object here.
public class ProjectDetailsAssembler {

    public ProjectDetailsData getData(String projectId) {

        // Construct the composite transfer object
        // get project related information from database and set to ProjectDetailsData class object.
        ProjectTO projectData = new ProjectTO();

        // get ProjectManager info and add to ProjectDetailsData
        ProjectManagerTO projectManagerData = new ProjectManagerTO();

        // construct a new TaskResourceTO using Task and Resource data.
        //get the Resource details from database.
        // construct a list of TaskResourceTOs
        Collection < TaskResourceTO > listOfTasks = new ArrayList < > ();


        // Add Project Info to ProjectDetailsData
        // Add ProjectManager info to ProjectDetailsData
        ProjectDetailsData pData = new ProjectDetailsData(projectData, projectManagerData, listOfTasks);
        return pData;
    }
}

Consequences

  • Separates business logic, simplifies client logic
  • Reduces coupling between clients and the application model
  • Improves network performance
  • Improves client performance
  • Can introduce stale data

References

Related Patterns

Comments