Merge pull request #608 from gopinath-langote/master

#348 Data Transfer Object design pattern
This commit is contained in:
Ilkka Seppälä
2017-08-17 22:15:38 +03:00
committed by GitHub
10 changed files with 438 additions and 0 deletions

View File

@ -0,0 +1,30 @@
---
layout: pattern
title: Data Transfer Object
folder: data-transfer-object
permalink: /patterns/data-transfer-object/
categories: Architectural
tags:
- Java
- KISS
- YAGNI
- Difficulty-Beginner
---
## Intent
Pass data with multiple attributes in one shot from client to server,
to avoid multiple calls to remote server.
![alt text](./etc/data-transfer-object.urm.png "data-transfer-object")
## Applicability
Use the Data Transfer Object pattern when
* The client is asking for multiple information. And the information is related.
* When you want to boost the performance to get resources.
* You want reduced number of remote calls.
## Credits
* [Design Pattern - Transfer Object Pattern](https://www.tutorialspoint.com/design_pattern/transfer_object_pattern.htm)
* [Data Transfer Object](https://msdn.microsoft.com/en-us/library/ff649585.aspx)

View File

@ -0,0 +1,48 @@
<?xml version="1.0" encoding="UTF-8"?>
<class-diagram version="1.2.0" icons="true" always-add-relationships="false" generalizations="true" realizations="true"
associations="true" dependencies="false" nesting-relationships="true" router="FAN">
<class id="1" language="java" name="com.iluwatar.datatransfer.CustomerClientApp" project="data-transfer-object"
file="/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerClientApp.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="145" y="93"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="2" language="java" name="com.iluwatar.datatransfer.CustomerDto" project="data-transfer-object"
file="/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="386" y="329"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<class id="3" language="java" name="com.iluwatar.datatransfer.CustomerResource" project="data-transfer-object"
file="/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java" binary="false"
corner="BOTTOM_RIGHT">
<position height="-1" width="-1" x="677" y="93"/>
<display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</display>
</class>
<association id="4">
<end type="SOURCE" refId="3" navigable="false">
<attribute id="5" name="customers"/>
<multiplicity id="6" minimum="0" maximum="2147483647"/>
</end>
<end type="TARGET" refId="2" navigable="true"/>
<display labels="true" multiplicity="true"/>
</association>
<classifier-display autosize="true" stereotype="true" package="true" initial-value="false" signature="true"
sort-features="false" accessors="true" visibility="true">
<attributes public="true" package="true" protected="true" private="true" static="true"/>
<operations public="true" package="true" protected="true" private="true" static="true"/>
</classifier-display>
<association-display labels="true" multiplicity="true"/>
</class-diagram>

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@ -0,0 +1,26 @@
@startuml
package com.iluwatar.datatransfer {
class CustomerClientApp {
+ CustomerClientApp()
+ main(args : String[]) {static}
- printCustomerDetails(allCustomers : List<CustomerDto>) {static}
}
class CustomerDto {
- firstName : String
- id : String
- lastName : String
+ CustomerDto(id : String, firstName : String, lastName : String)
+ getFirstName() : String
+ getId() : String
+ getLastName() : String
}
class CustomerResource {
- customers : List<CustomerDto>
+ CustomerResource(customers : List<CustomerDto>)
+ delete(customerId : String)
+ getAllCustomers() : List<CustomerDto>
+ save(customer : CustomerDto)
}
}
CustomerResource --> "-customers" CustomerDto
@enduml

View File

@ -0,0 +1,45 @@
<?xml version="1.0"?>
<!--
The MIT License
Copyright (c) 2016 Gopinath Langote
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
-->
<project xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd" xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>com.iluwatar</groupId>
<artifactId>java-design-patterns</artifactId>
<version>1.17.0-SNAPSHOT</version>
</parent>
<artifactId>data-transfer-object</artifactId>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</dependency>
</dependencies>
</project>

View File

@ -0,0 +1,84 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Gopinath Langote
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.iluwatar.datatransfer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.List;
/**
* The Data Transfer Object pattern is a design pattern in which an data transfer object is used to serve related
* information together to avoid multiple call for each piece of information.
* <p>
* In this example, ({@link CustomerClientApp}) as as customer details consumer i.e. client to request for
* customer details to server.
* <p>
* CustomerResource ({@link CustomerResource}) act as server to serve customer information.
* And The CustomerDto ({@link CustomerDto} is data transfer object to share customer information.
*/
public class CustomerClientApp {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomerClientApp.class);
/**
* Method as act client and request to server for details.
*
* @param args program argument.
*/
public static void main(String[] args) {
List<CustomerDto> customers = new ArrayList<>();
CustomerDto customerOne = new CustomerDto("1", "Kelly", "Brown");
CustomerDto customerTwo = new CustomerDto("2", "Alfonso", "Bass");
customers.add(customerOne);
customers.add(customerTwo);
CustomerResource customerResource = new CustomerResource(customers);
LOGGER.info("All customers:-");
List<CustomerDto> allCustomers = customerResource.getAllCustomers();
printCustomerDetails(allCustomers);
LOGGER.info("----------------------------------------------------------");
LOGGER.info("Deleting customer with id {1}");
customerResource.delete(customerOne.getId());
allCustomers = customerResource.getAllCustomers();
printCustomerDetails(allCustomers);
LOGGER.info("----------------------------------------------------------");
LOGGER.info("Adding customer three}");
CustomerDto customerThree = new CustomerDto("3", "Lynda", "Blair");
customerResource.save(customerThree);
allCustomers = customerResource.getAllCustomers();
printCustomerDetails(allCustomers);
}
private static void printCustomerDetails(List<CustomerDto> allCustomers) {
allCustomers.forEach(customer -> LOGGER.info(customer.getFirstName()));
}
}

View File

@ -0,0 +1,60 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Gopinath Langote
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.iluwatar.datatransfer;
/**
* {@link CustomerDto} is a data transfer object POJO. Instead of sending individual information to client
* We can send related information together in POJO.
* <p>
* Dto will not have any business logic in it.
*/
public class CustomerDto {
private final String id;
private final String firstName;
private final String lastName;
/**
* @param id customer id
* @param firstName customer first name
* @param lastName customer last name
*/
public CustomerDto(String id, String firstName, String lastName) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
}
public String getId() {
return id;
}
public String getFirstName() {
return firstName;
}
public String getLastName() {
return lastName;
}
}

View File

@ -0,0 +1,63 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Gopinath Langote
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.iluwatar.datatransfer;
import java.util.List;
/**
* The resource class which serves customer information.
* This class act as server in the demo. Which has all customer details.
*/
public class CustomerResource {
private List<CustomerDto> customers;
/**
* @param customers initialize resource with existing customers. Act as database.
*/
public CustomerResource(List<CustomerDto> customers) {
this.customers = customers;
}
/**
* @return : all customers in list.
*/
public List<CustomerDto> getAllCustomers() {
return customers;
}
/**
* @param customer save new customer to list.
*/
public void save(CustomerDto customer) {
customers.add(customer);
}
/**
* @param customerId delete customer with id {@code customerId}
*/
public void delete(String customerId) {
customers.removeIf(customer -> customer.getId().equals(customerId));
}
}

View File

@ -0,0 +1,81 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2017 Gopinath Langote
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in all
* copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
* SOFTWARE.
*/
package com.iluwatar.datatransfer;
import org.junit.Test;
import java.util.ArrayList;
import java.util.List;
import static org.junit.Assert.assertEquals;
/**
* tests {@link CustomerResource}.
*/
public class CustomerResourceTest {
@Test
public void shouldGetAllCustomers() {
CustomerDto customer = new CustomerDto("1", "Melody", "Yates");
List<CustomerDto> customers = new ArrayList<>();
customers.add(customer);
CustomerResource customerResource = new CustomerResource(customers);
List<CustomerDto> allCustomers = customerResource.getAllCustomers();
assertEquals(allCustomers.size(), 1);
assertEquals(allCustomers.get(0).getId(), "1");
assertEquals(allCustomers.get(0).getFirstName(), "Melody");
assertEquals(allCustomers.get(0).getLastName(), "Yates");
}
@Test
public void shouldSaveCustomer() {
CustomerDto customer = new CustomerDto("1", "Rita", "Reynolds");
CustomerResource customerResource = new CustomerResource(new ArrayList<>());
customerResource.save(customer);
List<CustomerDto> allCustomers = customerResource.getAllCustomers();
assertEquals(allCustomers.get(0).getId(), "1");
assertEquals(allCustomers.get(0).getFirstName(), "Rita");
assertEquals(allCustomers.get(0).getLastName(), "Reynolds");
}
@Test
public void shouldDeleteCustomer() {
CustomerDto customer = new CustomerDto("1", "Terry", "Nguyen");
List<CustomerDto> customers = new ArrayList<>();
customers.add(customer);
CustomerResource customerResource = new CustomerResource(customers);
customerResource.delete(customer.getId());
List<CustomerDto> allCustomers = customerResource.getAllCustomers();
assertEquals(allCustomers.size(), 0);
}
}

View File

@ -143,6 +143,7 @@
<module>extension-objects</module> <module>extension-objects</module>
<module>marker</module> <module>marker</module>
<module>cqrs</module> <module>cqrs</module>
<module>data-transfer-object</module>
</modules> </modules>