diff --git a/data-transfer-object-enum-impl/README.md b/data-transfer-object-enum-impl/README.md deleted file mode 100644 index 7e6dbc365..000000000 --- a/data-transfer-object-enum-impl/README.md +++ /dev/null @@ -1,54 +0,0 @@ ---- -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) diff --git a/data-transfer-object-enum-impl/etc/data-transfer-object-enum-impl.urm.puml b/data-transfer-object-enum-impl/etc/data-transfer-object-enum-impl.urm.puml deleted file mode 100644 index e6426c392..000000000 --- a/data-transfer-object-enum-impl/etc/data-transfer-object-enum-impl.urm.puml +++ /dev/null @@ -1,129 +0,0 @@ -@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 - + ProductResource(products : List) - + getAllProductsForAdmin() : List - + getAllProductsForCustomer() : List - + getProducts() : List - + 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 diff --git a/data-transfer-object-enum-impl/etc/dto-enum-uml.png b/data-transfer-object-enum-impl/etc/dto-enum-uml.png deleted file mode 100644 index 57e9a1ab5..000000000 Binary files a/data-transfer-object-enum-impl/etc/dto-enum-uml.png and /dev/null differ diff --git a/data-transfer-object-enum-impl/pom.xml b/data-transfer-object-enum-impl/pom.xml deleted file mode 100644 index 74c8a3a6c..000000000 --- a/data-transfer-object-enum-impl/pom.xml +++ /dev/null @@ -1,61 +0,0 @@ - - - - 4.0.0 - - com.iluwatar - java-design-patterns - 1.24.0-SNAPSHOT - - data-transfer-object-enum-impl - - - org.junit.jupiter - junit-jupiter-engine - test - - - - - - org.apache.maven.plugins - maven-assembly-plugin - - - - - - com.iluwatar.datatransferenum.App - - - - - - - - - diff --git a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/App.java b/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/App.java deleted file mode 100644 index 9c80d07cc..000000000 --- a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/App.java +++ /dev/null @@ -1,59 +0,0 @@ -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. - * - *

In this example, ({@link App}) as as product details consumer i.e. client to - * request for product details to server. - * - *

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 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())); - } -} diff --git a/data-transfer-object-enum-impl/src/test/java/com/iluwatar/datatransferenum/AppTest.java b/data-transfer-object-enum-impl/src/test/java/com/iluwatar/datatransferenum/AppTest.java deleted file mode 100644 index bba131e64..000000000 --- a/data-transfer-object-enum-impl/src/test/java/com/iluwatar/datatransferenum/AppTest.java +++ /dev/null @@ -1,44 +0,0 @@ -/* - * 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. - */ - -package com.iluwatar.datatransferenum; - -import static org.junit.jupiter.api.Assertions.assertDoesNotThrow; - - -import org.junit.jupiter.api.Test; - -class AppTest { - - /** - * Issue: Add at least one assertion to this test case. - *

- * Solution: Inserted assertion to check whether the execution of the main method in {@link App#main(String[])} - * throws an exception. - */ - - @Test - void shouldExecuteApplicationWithoutException() { - assertDoesNotThrow(() -> App.main(new String[] {})); - } -} diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java index b8630d4ea..5bee4e27f 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/App.java @@ -23,7 +23,13 @@ package com.iluwatar.datatransfer; +import com.iluwatar.datatransfer.customer.CustomerDto; +import com.iluwatar.datatransfer.customer.CustomerResource; +import com.iluwatar.datatransfer.product.Product; +import com.iluwatar.datatransfer.product.ProductDto; +import com.iluwatar.datatransfer.product.ProductResource; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -32,11 +38,17 @@ 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. * - *

In this example, ({@link App}) as as customer details consumer i.e. client to - * request for customer details to server. + *

In the first example, {@link App} is a customer details consumer i.e. client to + * request for customer details to server. {@link CustomerResource} act as server to serve customer + * information. {@link CustomerDto} is data transfer object to share customer information. + * + *

In the second example, {@link App} is a product details consumer i.e. client to + * request for product details to server. {@link ProductResource} acts as server to serve + * product information. {@link ProductDto} is data transfer object to share product information. + * + *

The pattern implementation is a bit different in each of the examples. The first can be + * thought as a traditional example and the second is an enum based implementation. * - *

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 App { @@ -48,6 +60,8 @@ public class App { * @param args program argument. */ public static void main(String[] args) { + + // Example 1: Customer DTO var customerOne = new CustomerDto("1", "Kelly", "Brown"); var customerTwo = new CustomerDto("2", "Alfonso", "Bass"); var customers = new ArrayList<>(List.of(customerOne, customerTwo)); @@ -72,6 +86,53 @@ public class App { customerResource.save(customerThree); allCustomers = customerResource.getAllCustomers(); printCustomerDetails(allCustomers); + + // Example 2: Product DTO + 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 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())); } private static void printCustomerDetails(List allCustomers) { diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerDto.java similarity index 97% rename from data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerDto.java index a77eb8702..50d3a0857 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerDto.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerDto.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.iluwatar.datatransfer; +package com.iluwatar.datatransfer.customer; /** * {@link CustomerDto} is a data transfer object POJO. Instead of sending individual information to diff --git a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerResource.java similarity index 98% rename from data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerResource.java index d0a153f6f..edd3fcb6d 100644 --- a/data-transfer-object/src/main/java/com/iluwatar/datatransfer/CustomerResource.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/customer/CustomerResource.java @@ -21,7 +21,7 @@ * THE SOFTWARE. */ -package com.iluwatar.datatransfer; +package com.iluwatar.datatransfer.customer; import java.util.List; diff --git a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/Product.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/Product.java similarity index 58% rename from data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/Product.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/Product.java index 96758baf4..698052efe 100644 --- a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/Product.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/Product.java @@ -1,4 +1,27 @@ -package com.iluwatar.datatransferenum; +/* + * 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. + */ + +package com.iluwatar.datatransfer.product; /** * {@link Product} is a entity class for product entity. This class act as entity in the demo. diff --git a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductDto.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductDto.java similarity index 82% rename from data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductDto.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductDto.java index 49d08d896..97c2acd05 100644 --- a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductDto.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductDto.java @@ -1,4 +1,27 @@ -package com.iluwatar.datatransferenum; +/* + * 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. + */ + +package com.iluwatar.datatransfer.product; /** * {@link ProductDto} is a data transfer object POJO. diff --git a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductResource.java b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductResource.java similarity index 62% rename from data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductResource.java rename to data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductResource.java index 5940982b1..abb869254 100644 --- a/data-transfer-object-enum-impl/src/main/java/com/iluwatar/datatransferenum/ProductResource.java +++ b/data-transfer-object/src/main/java/com/iluwatar/datatransfer/product/ProductResource.java @@ -1,4 +1,27 @@ -package com.iluwatar.datatransferenum; +/* + * 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. + */ + +package com.iluwatar.datatransfer.product; import java.util.List; import java.util.stream.Collectors; diff --git a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/customer/CustomerResourceTest.java similarity index 94% rename from data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java rename to data-transfer-object/src/test/java/com/iluwatar/datatransfer/customer/CustomerResourceTest.java index 7765fd5bf..8b2d0d92a 100644 --- a/data-transfer-object/src/test/java/com/iluwatar/datatransfer/CustomerResourceTest.java +++ b/data-transfer-object/src/test/java/com/iluwatar/datatransfer/customer/CustomerResourceTest.java @@ -21,13 +21,16 @@ * THE SOFTWARE. */ -package com.iluwatar.datatransfer; +package com.iluwatar.datatransfer.customer; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.junit.jupiter.api.Assertions.assertTrue; import java.util.ArrayList; import java.util.List; + +import com.iluwatar.datatransfer.customer.CustomerDto; +import com.iluwatar.datatransfer.customer.CustomerResource; import org.junit.jupiter.api.Test; /** diff --git a/pom.xml b/pom.xml index 38e702761..eee0cb154 100644 --- a/pom.xml +++ b/pom.xml @@ -199,7 +199,6 @@ filterer factory separated-interface - data-transfer-object-enum-impl special-case