Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Browse files
Browse the repository at this point in the history
* #1569 DTO pattern implemented using Enums * #1569 DTO pattern implemented using Enums * #1569 adding some java docs * #1569 some changes in java doc and code style * #1569 some changes in java doc and code style * #1569 some changes in java doc and code style * #1569 some changes in java doc and code style * #1569 adding suggested extra line * #1569 license added to pom.xml * #1569 more checkstyle problems resolved * #1569 more checkstyle problems resolved * #1569 more checkstyle problems resolved Co-authored-by: siavashsoleymani <siavash.soleimani@snapp.cab> Co-authored-by: Subhrodip Mohanta <subhrodipmohanta@gmail.com>
- Loading branch information
1 parent
a94615a
commit 5bc61c8
Showing
10 changed files
with
774 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,54 @@ | ||
--- | ||
layout: pattern | ||
title: Data Transfer Object | ||
folder: data-transfer-object | ||
permalink: /patterns/data-transfer-object/ | ||
categories: Architectural | ||
tags: | ||
- Performance | ||
--- | ||
|
||
## Intent | ||
|
||
Pass data with multiple attributes in one shot from client to server, to avoid multiple calls to | ||
remote server. | ||
|
||
## Explanation | ||
|
||
Real world example | ||
|
||
> We need to fetch information about customers from remote database. Instead of querying the | ||
> attributes one at a time, we use DTOs to transfer all the relevant attributes in a single shot. | ||
In plain words | ||
|
||
> Using DTO relevant information can be fetched with a single backend query. | ||
Wikipedia says | ||
|
||
> In the field of programming a data transfer object (DTO) is an object that carries data between | ||
> processes. The motivation for its use is that communication between processes is usually done | ||
> resorting to remote interfaces (e.g. web services), where each call is an expensive operation. | ||
> Because the majority of the cost of each call is related to the round-trip time between the client | ||
> and the server, one way of reducing the number of calls is to use an object (the DTO) that | ||
> aggregates the data that would have been transferred by the several calls, but that is served by | ||
> one call only. | ||
## Class diagram | ||
|
||
![alt text](./etc/dto-enum-uml.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) | ||
* [J2EE Design Patterns](https://www.amazon.com/gp/product/0596004273/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0596004273&linkCode=as2&tag=javadesignpat-20&linkId=f27d2644fbe5026ea448791a8ad09c94) | ||
* [Patterns of Enterprise Application Architecture](https://www.amazon.com/gp/product/0321127420/ref=as_li_tl?ie=UTF8&camp=1789&creative=9325&creativeASIN=0321127420&linkCode=as2&tag=javadesignpat-20&linkId=014237a67c9d46f384b35e10151956bd) |
129 changes: 129 additions & 0 deletions
129
data-transfer-object-enum-impl/etc/data-transfer-object-enum-impl.urm.puml
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,129 @@ | ||
@startuml | ||
package com.iluwatar.datatransferenum { | ||
class App { | ||
- LOGGER : Logger {static} | ||
+ App() | ||
+ main(args : String[]) {static} | ||
} | ||
class Product { | ||
- cost : Double | ||
- id : Long | ||
- name : String | ||
- price : Double | ||
- supplier : String | ||
+ Product() | ||
+ getCost() : Double | ||
+ getId() : Long | ||
+ getName() : String | ||
+ getPrice() : Double | ||
+ getSupplier() : String | ||
+ setCost(cost : Double) : Product | ||
+ setId(id : Long) : Product | ||
+ setName(name : String) : Product | ||
+ setPrice(price : Double) : Product | ||
+ setSupplier(supplier : String) : Product | ||
+ toString() : String | ||
} | ||
enum ProductDTO { | ||
+ valueOf(name : String) : ProductDTO {static} | ||
+ values() : ProductDTO[] {static} | ||
} | ||
-interface Cost { | ||
+ getCost() : Double {abstract} | ||
} | ||
-interface Id { | ||
+ getId() : Long {abstract} | ||
} | ||
-interface Name { | ||
+ getName() : String {abstract} | ||
} | ||
-interface Price { | ||
+ getPrice() : Double {abstract} | ||
} | ||
enum Request { | ||
+ valueOf(name : String) : Request {static} | ||
+ values() : Request[] {static} | ||
} | ||
class Create { | ||
- cost : Double | ||
- name : String | ||
- price : Double | ||
- supplier : String | ||
+ Create() | ||
+ getCost() : Double | ||
+ getName() : String | ||
+ getPrice() : Double | ||
+ getSupplier() : String | ||
+ setCost(cost : Double) : Create | ||
+ setName(name : String) : Create | ||
+ setPrice(price : Double) : Create | ||
+ setSupplier(supplier : String) : Create | ||
} | ||
enum Response { | ||
+ valueOf(name : String) : Response {static} | ||
+ values() : Response[] {static} | ||
} | ||
class Private { | ||
- cost : Double | ||
- id : Long | ||
- name : String | ||
- price : Double | ||
+ Private() | ||
+ getCost() : Double | ||
+ getId() : Long | ||
+ getName() : String | ||
+ getPrice() : Double | ||
+ setCost(cost : Double) : Private | ||
+ setId(id : Long) : Private | ||
+ setName(name : String) : Private | ||
+ setPrice(price : Double) : Private | ||
+ toString() : String | ||
} | ||
class Public { | ||
- id : Long | ||
- name : String | ||
- price : Double | ||
+ Public() | ||
+ getId() : Long | ||
+ getName() : String | ||
+ getPrice() : Double | ||
+ setId(id : Long) : Public | ||
+ setName(name : String) : Public | ||
+ setPrice(price : Double) : Public | ||
+ toString() : String | ||
} | ||
-interface Supplier { | ||
+ getSupplier() : String {abstract} | ||
} | ||
class ProductResource { | ||
- products : List<Product> | ||
+ ProductResource(products : List<Product>) | ||
+ getAllProductsForAdmin() : List<Private> | ||
+ getAllProductsForCustomer() : List<Public> | ||
+ getProducts() : List<Product> | ||
+ save(createProductDTO : Create) | ||
} | ||
} | ||
Create ..+ Request | ||
Request ..+ ProductDTO | ||
Private ..+ Response | ||
Supplier ..+ ProductDTO | ||
Name ..+ ProductDTO | ||
ProductResource --> "-products" Product | ||
Public ..+ Response | ||
Id ..+ ProductDTO | ||
Price ..+ ProductDTO | ||
Response ..+ ProductDTO | ||
Cost ..+ ProductDTO | ||
Create ..|> Name | ||
Create ..|> Price | ||
Create ..|> Cost | ||
Create ..|> Supplier | ||
Private ..|> Id | ||
Private ..|> Name | ||
Private ..|> Price | ||
Private ..|> Cost | ||
Public ..|> Id | ||
Public ..|> Name | ||
Public ..|> Price | ||
@enduml |
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
<?xml version="1.0" encoding="UTF-8"?> | ||
<!-- | ||
The MIT License | ||
Copyright © 2014-2019 Ilkka Seppälä | ||
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 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
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"> | ||
<modelVersion>4.0.0</modelVersion> | ||
<parent> | ||
<groupId>com.iluwatar</groupId> | ||
<artifactId>java-design-patterns</artifactId> | ||
<version>1.24.0-SNAPSHOT</version> | ||
</parent> | ||
<artifactId>data-transfer-object-enum-impl</artifactId> | ||
<dependencies> | ||
<dependency> | ||
<groupId>org.junit.jupiter</groupId> | ||
<artifactId>junit-jupiter-engine</artifactId> | ||
<scope>test</scope> | ||
</dependency> | ||
</dependencies> | ||
<build> | ||
<plugins> | ||
<plugin> | ||
<groupId>org.apache.maven.plugins</groupId> | ||
<artifactId>maven-assembly-plugin</artifactId> | ||
<executions> | ||
<execution> | ||
<configuration> | ||
<archive> | ||
<manifest> | ||
<mainClass>com.iluwatar.datatransferenum.App</mainClass> | ||
</manifest> | ||
</archive> | ||
</configuration> | ||
</execution> | ||
</executions> | ||
</plugin> | ||
</plugins> | ||
</build> | ||
</project> |
59 changes: 59 additions & 0 deletions
59
data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/App.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,59 @@ | ||
package com.iluwatar.datatransferenum; | ||
|
||
import java.util.ArrayList; | ||
import java.util.Arrays; | ||
import java.util.List; | ||
import org.slf4j.Logger; | ||
import org.slf4j.LoggerFactory; | ||
|
||
/** | ||
* 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 App}) as as product details consumer i.e. client to | ||
* request for product details to server. | ||
* | ||
* <p>productResource ({@link ProductResource}) act as server to serve product information. And | ||
* The productDto ({@link ProductDto} is data transfer object to share product information. | ||
*/ | ||
public class App { | ||
|
||
private static final Logger LOGGER = LoggerFactory.getLogger(App.class); | ||
|
||
/** | ||
* Method as act client and request to server for details. | ||
* | ||
* @param args program argument. | ||
*/ | ||
public static void main(String[] args) { | ||
Product tv = | ||
new Product().setId(1L).setName("TV").setSupplier("Sony").setPrice(1000D).setCost(1090D); | ||
Product microwave = | ||
new Product().setId(2L).setName("microwave").setSupplier("Delonghi").setPrice(1000D) | ||
.setCost(1090D); | ||
Product refrigerator = | ||
new Product().setId(3L).setName("refrigerator").setSupplier("Botsch").setPrice(1000D) | ||
.setCost(1090D); | ||
Product airConditioner = | ||
new Product().setId(4L).setName("airConditioner").setSupplier("LG").setPrice(1000D) | ||
.setCost(1090D); | ||
List<Product> products = | ||
new ArrayList<>(Arrays.asList(tv, microwave, refrigerator, airConditioner)); | ||
ProductResource productResource = new ProductResource(products); | ||
|
||
LOGGER.info("####### List of products including sensitive data just for admins: \n {}", | ||
Arrays.toString(productResource.getAllProductsForAdmin().toArray())); | ||
LOGGER.info("####### List of products for customers: \n {}", | ||
Arrays.toString(productResource.getAllProductsForCustomer().toArray())); | ||
|
||
LOGGER.info("####### Going to save Sony PS5 ..."); | ||
ProductDto.Request.Create createProductRequestDto = new ProductDto.Request.Create() | ||
.setName("PS5") | ||
.setCost(1000D) | ||
.setPrice(1220D) | ||
.setSupplier("Sony"); | ||
productResource.save(createProductRequestDto); | ||
LOGGER.info("####### List of products after adding PS5: {}", | ||
Arrays.toString(productResource.getProducts().toArray())); | ||
} | ||
} |
91 changes: 91 additions & 0 deletions
91
data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/Product.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,91 @@ | ||
package com.iluwatar.datatransferenum; | ||
|
||
/** | ||
* {@link Product} is a entity class for product entity. This class act as entity in the demo. | ||
*/ | ||
public final class Product { | ||
private Long id; | ||
private String name; | ||
private Double price; | ||
private Double cost; | ||
private String supplier; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param id product id | ||
* @param name product name | ||
* @param price product price | ||
* @param cost product cost | ||
* @param supplier product supplier | ||
*/ | ||
public Product(Long id, String name, Double price, Double cost, String supplier) { | ||
this.id = id; | ||
this.name = name; | ||
this.price = price; | ||
this.cost = cost; | ||
this.supplier = supplier; | ||
} | ||
|
||
/** | ||
* Constructor. | ||
*/ | ||
public Product() { | ||
} | ||
|
||
public Long getId() { | ||
return id; | ||
} | ||
|
||
public Product setId(Long id) { | ||
this.id = id; | ||
return this; | ||
} | ||
|
||
public String getName() { | ||
return name; | ||
} | ||
|
||
public Product setName(String name) { | ||
this.name = name; | ||
return this; | ||
} | ||
|
||
public Double getPrice() { | ||
return price; | ||
} | ||
|
||
public Product setPrice(Double price) { | ||
this.price = price; | ||
return this; | ||
} | ||
|
||
public Double getCost() { | ||
return cost; | ||
} | ||
|
||
public Product setCost(Double cost) { | ||
this.cost = cost; | ||
return this; | ||
} | ||
|
||
public String getSupplier() { | ||
return supplier; | ||
} | ||
|
||
public Product setSupplier(String supplier) { | ||
this.supplier = supplier; | ||
return this; | ||
} | ||
|
||
@Override | ||
public String toString() { | ||
return "Product{" | ||
+ "id=" + id | ||
+ ", name='" + name + '\'' | ||
+ ", price=" + price | ||
+ ", cost=" + cost | ||
+ ", supplier='" + supplier + '\'' | ||
+ '}'; | ||
} | ||
} |
Oops, something went wrong.