diff --git a/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/AppTest.java b/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/AppTest.java index e161b2edc30d..b72f5bffaac5 100644 --- a/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/AppTest.java +++ b/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/AppTest.java @@ -1,3 +1,27 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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.idempotentconsumer; import org.junit.jupiter.api.Test; diff --git a/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/RequestStateMachineTests.java b/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/RequestStateMachineTests.java index af779648c8a3..083cff7ad05e 100644 --- a/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/RequestStateMachineTests.java +++ b/microservices-idempotent-consumer/src/test/java/com/iluwatar/idempotentconsumer/RequestStateMachineTests.java @@ -1,3 +1,27 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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.idempotentconsumer; import org.junit.jupiter.api.BeforeEach; diff --git a/pom.xml b/pom.xml index ef3a39265d53..c1cc996ab1d0 100644 --- a/pom.xml +++ b/pom.xml @@ -218,6 +218,7 @@ function-composition microservices-distributed-tracing microservices-idempotent-consumer + two-step-view diff --git a/two-step-view/README.md b/two-step-view/README.md new file mode 100644 index 000000000000..018df900c461 --- /dev/null +++ b/two-step-view/README.md @@ -0,0 +1,156 @@ +# Two-Step View + + +--- + +## Also known as + +- Template View. +- Model-View Separation +- Separated Presentation +- View Helper Pattern +--- + +## Intent of Two-Step View Design Pattern +- **Decouple Data and Presentation**: Separate data preparation from rendering for better modularity. +- **Reusable Rendering**: Use templates to reduce duplication. +- **Flexibility**: Render the same data differently with various templates. +- **Maintainability**: Simplify testing and updates by isolating logic. +- **Multi-Format Support**: Prepare data once and render in formats like HTML or JSON. +--- + +## Detailed Explanation of the Two Step View Pattern with Real-World Examples + +**Real-World Example**: +Imagine a restaurant kitchen. + +**Step 1**: Preparation – The chef cooks and plates the food, ensuring it is ready to be served. + +**Step 2**: Presentation – The waiter serves the plated food to the customer, adding any final touches, such as garnishes. + +**In Plain Words**: The Two-Step View Pattern separates the process of preparing data from how it is presented. + +**Authoritative Source**: Martin Fowler describes the Two-Step View pattern as transforming domain data into HTML in two stages: first by creating a logical page, then rendering it into HTML.(https://martinfowler.com/eaaCatalog/twoStepView.html) + +--- + +## Programmatic Example of Two-Step View Pattern in Java + + +#### **Phase 1: Data Preparation (`DataPreparation`)** +- **Responsibility:** Processes raw `Book` data by calculating the discount price and checking stock availability. +- **Method:** `prepareBook(Book book)` +- **Output:** Returns a `BookStore` object with processed details. +- **Example:** + ```java + BookStore bookStore = DataPreparation.prepareBook(book); + ``` + +#### **Phase 2: Presentation (`Presentation`)** +- **Responsibility:** Converts the prepared `BookStore` data into an HTML representation. +- **Method:** `presentBook(BookStore bookInStore)` +- **Output:** HTML formatted book details. +- **Example:** + ```java + String bookHtml = Presentation.presentBook(bookStore); + ``` + + + +--- + +## When to Use the Two Step View Pattern in Java + +- **Separation of Logic:** When you need to separate data preparation from presentation for better modularity. +- **Multiple Formats:** When the same data needs to be rendered in multiple formats (e.g., HTML, JSON, XML). +- **Reusable Templates:** When you want to reuse rendering logic across different parts of the application. +- **Maintainability:** When frequent changes in the presentation layer shouldn't impact the business logic or data preparation. +- **Flexibility:** When different rendering methods are required for the same prepared data based on user preferences or contexts. +- **Scalability:** When adding new presentation formats without affecting existing preparation logic is needed. +- **MVC Architecture:** When implementing the Model-View-Controller (MVC) design pattern, where the model (data preparation) and view (presentation) are distinctly separate. +- **Testability:** When isolating and unit testing data preparation and rendering logic independently is a priority. +--- +## Two-Step View Pattern Java Tutorials + + +- **Martin Fowler's Explanation**: Martin Fowler discusses the Two-Step View pattern, detailing its application in transforming domain data into HTML in two stages.(https://martinfowler.com/eaaCatalog/twoStepView) + +- **Stack Overflow Discussion**: A discussion on Stack Overflow explores the implementation of the Two Step View pattern in Spring MVC, highlighting its benefits and practical considerations.(https://stackoverflow.com/questions/58114790/spring-mvc-one-step-view-or-two-step-view) + +- **Java Design Patterns Tutorial**: This comprehensive tutorial covers various design patterns in Java, including structural patterns that may relate to the Two Step View pattern.(https://www.digitalocean.com/community/tutorials/java-design-patterns-example-tutorial) + + + +--- +## Real-World Applications of Two-Step View Pattern in Java + +- **Spring MVC**: Separates the logic of data preparation from view rendering, using technologies like JSP, Thymeleaf, or FreeMarker. ([Stack Overflow discussion](https://stackoverflow.com/questions/58114790/spring-mvc-one-step-view-or-two-step-view)) +- **Composite View Pattern**: Similar to Two Step View, this pattern involves composing view components into tree structures, promoting separation of concerns. ([Java Design Patterns - Composite View](https://java-design-patterns.com/patterns/composite-view/?utm_source=chatgpt.com)) +- **Martin Fowler's Two Step View**: A foundational explanation of transforming domain data into HTML in two stages, applied in web applications. ([martinfowler.com](https://martinfowler.com/eaaCatalog/twoStepView.html?utm_source=chatgpt.com)) +--- +### **Benefits of the Two Step View Pattern** + +- **Separation of Concerns:** Separates data processing from presentation logic, making the system more modular and easier to maintain. +- **Reusability:** Data preparation and presentation can be reused independently across different views or formats. +- **Flexibility:** Easily switch or modify the presentation layer (e.g., HTML, XML, JSON) without changing the underlying data logic. +- **Maintainability:** Changes in the data model or presentation logic are isolated, reducing the risk of side effects. +- **Testability:** Each phase (data preparation and rendering) can be unit tested independently, improving code quality and reliability. +- **Scalability:** Adding new views or presentation formats becomes easier without altering the core business logic. +--- + +## **Trade-offs of the Two Step View Pattern** + +- **Increased Complexity:** Implementing two separate steps adds complexity, particularly in smaller applications where a simple approach may suffice. +- **Performance Overhead:** Dividing the logic into two phases may introduce unnecessary overhead, especially in performance-critical applications. +- **Over-engineering:** For simple applications, the pattern might be overkill, leading to unnecessary abstraction. +- **Tighter Coupling of Phases:** If not designed properly, the two phases (data preparation and presentation) might still become tightly coupled, reducing the pattern's effectiveness. +- **Development Time:** The initial implementation of two phases may require more time compared to simpler, more straightforward methods. +--- +## **Related Java Design Patterns** + +- **Model-View-Controller (MVC):** Separates data (Model), presentation (View), and user interaction (Controller), which is conceptually similar to the Two Step View pattern. + [Learn more](https://refactoring.guru/design-patterns/mvc) + +- **Composite View:** Builds complex views by combining multiple components into a tree structure, promoting modularity in rendering views. + [Learn more](https://java-design-patterns.com/patterns/composite-view/?utm_source=chatgpt.com) + +- **Template Method:** Defines the structure of an algorithm but allows certain steps to be implemented by subclasses, similar to separating data preparation from presentation. + [Learn more](https://refactoring.guru/design-patterns/template-method) + +- **Strategy Pattern:** Allows the selection of algorithms (e.g., data preparation or presentation rendering) at runtime, offering flexibility in handling multiple views. + [Learn more](https://refactoring.guru/design-patterns/strategy) + +- **Decorator Pattern:** Adds behavior or functionality to an object dynamically, which can be useful for enhancing view rendering capabilities. + [Learn more](https://refactoring.guru/design-patterns/decorator) + +- **Abstract Factory Pattern:** Creates families of related objects without specifying their concrete classes, similar to abstracting view rendering across different formats. + [Learn more](https://refactoring.guru/design-patterns/abstract-factory) +--- +## **References and Credits for the Two Step View Pattern** + +- **"Patterns of Enterprise Application Architecture"** by Martin Fowler + A key resource explaining the Two Step View pattern, among other enterprise application design patterns. + [Link to book](https://martinfowler.com/books/eaa.html) + +- **"Design Patterns: Elements of Reusable Object-Oriented Software"** by Erich Gamma, Richard Helm, Ralph Johnson, and John Vlissides + This book outlines foundational design patterns that are conceptually related to the Two Step View pattern, like MVC and Composite View. + [Link to book](https://www.pearson.com/store/p/design-patterns-elements-of-reusable-object-oriented-software/P100000825256) + +- **"Refactoring: Improving the Design of Existing Code"** by Martin Fowler + Discusses how to refactor code in a way that aligns with the principles of modularity and separation of concerns, which are also key goals of the Two Step View pattern. + [Link to book](https://martinfowler.com/books/refactoring.html) + +- **"Head First Design Patterns"** by Eric Freeman and Elisabeth Robson + A beginner-friendly resource that explains various design patterns, including those related to view rendering, like MVC and Composite View. + [Link to book](https://www.oreilly.com/library/view/head-first-design/9780596007126/) + +- **"Java Design Patterns: A Hands-On Experience with Real-World Examples"** by Vaskaran Sarcar + Provides practical examples of design patterns in Java, with potential applications for the Two Step View pattern. + [Link to book](https://www.amazon.com/Java-Design-Patterns-Hands-Experience/dp/1788621754) + +- **"Design Patterns in Java"** by Steven John Metsker + A book that covers Java-specific examples of design patterns and explores how they can be used effectively in enterprise applications. + [Link to book](https://www.amazon.com/Design-Patterns-Java-Steven-Metsker/dp/0321192958) + + + diff --git a/two-step-view/pom.xml b/two-step-view/pom.xml new file mode 100644 index 000000000000..ac1046847e91 --- /dev/null +++ b/two-step-view/pom.xml @@ -0,0 +1,65 @@ + + + + 4.0.0 + + com.iluwatar + java-design-patterns + 1.26.0-SNAPSHOT + + + two-step-view + + + junit + junit + test + + + + + + org.apache.maven.plugins + maven-assembly-plugin + + + + + + com.iluwatar.model.view.presenter.App + + + + + + + + + \ No newline at end of file diff --git a/two-step-view/src/main/java/com/iluwatar/App.java b/two-step-view/src/main/java/com/iluwatar/App.java new file mode 100644 index 000000000000..9a242efcbee5 --- /dev/null +++ b/two-step-view/src/main/java/com/iluwatar/App.java @@ -0,0 +1,60 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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; + +import java.util.logging.Logger; + +/* + * The Two Step View Pattern: + * Separates generating dynamic web content into: + * 1. Data Preparation: Raw data is structured for presentation. + * 2. Data Presentation: Prepared data is rendered into a display format (e.g., HTML). + * This enhances modularity, maintainability, and testability by decoupling preparation and presentation. + + * Implementation in this Example: + * 1. Data Preparation: `DataPreparation` transforms a `Book` into a `BookStore` object, calculating discount prices and stock status. + * 2. Data Presentation: `Presentation` generates an HTML view of the `BookStore` object, focusing only on rendering. + */ + +/** Main class. */ +public class App { + private static final Logger logger = Logger.getLogger(App.class.getName()); + + /** Main function. */ + public static void main(String[] args) { + // Create a Book instance with sample data + Book book = new Book("Batman Vol. 1: The Court of Owls", 11.60, true, 10); + + // Convert raw book data into a structured format + BookStore preparedData = DataPreparation.prepareBook(book); + + // Converts the prepared book data into an HTML string for display + String htmlOutput = Presentation.presentBook(preparedData); + + // Output the rendered HTML + logger.info(htmlOutput); + } +} + diff --git a/two-step-view/src/main/java/com/iluwatar/Book.java b/two-step-view/src/main/java/com/iluwatar/Book.java new file mode 100644 index 000000000000..add59c4db181 --- /dev/null +++ b/two-step-view/src/main/java/com/iluwatar/Book.java @@ -0,0 +1,47 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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; +import lombok.Data; + +/** Represents a Book. */ +@Data +public class Book { + String name; + double price; + boolean discount; + int stock; + Book(String name, double price, boolean discount, int stock) { + if (!name.isEmpty()) { // Make sure is not empty + this.name = name; + } + if (price > 0) { // Make sure price is set with a realistic value + this.price = price; + } + if (stock >= 0) { // Make sure stock is not negative + this.stock = stock; + } + this.discount = discount; + } +} diff --git a/two-step-view/src/main/java/com/iluwatar/BookStore.java b/two-step-view/src/main/java/com/iluwatar/BookStore.java new file mode 100644 index 000000000000..c3d14386883c --- /dev/null +++ b/two-step-view/src/main/java/com/iluwatar/BookStore.java @@ -0,0 +1,39 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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; + +import lombok.AllArgsConstructor; +import lombok.Data; + +/** Represents the processed book data used for display purposes. */ +@AllArgsConstructor +@Data +public class BookStore { + String name; + double price; + double discountPrice; // Calculates price if the book is discounted + boolean inStock; // Indicates if the book is in stock + +} diff --git a/two-step-view/src/main/java/com/iluwatar/DataPreparation.java b/two-step-view/src/main/java/com/iluwatar/DataPreparation.java new file mode 100644 index 000000000000..3d25e92d9e93 --- /dev/null +++ b/two-step-view/src/main/java/com/iluwatar/DataPreparation.java @@ -0,0 +1,43 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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; + + + +/** class representing phase 1. */ +public class DataPreparation { + + private DataPreparation() {} + /** + * Prepares book data for the store. + * Calculates the discount price if applicable and checks stock availability. + */ + + public static BookStore prepareBook(Book book) { + double discountPrice = book.isDiscount() ? book.getPrice() * 0.75 : book.getPrice(); + boolean inStock = book.getStock() > 0; + return new BookStore(book.getName(), book.getPrice(), discountPrice, inStock); + } +} diff --git a/two-step-view/src/main/java/com/iluwatar/Presentation.java b/two-step-view/src/main/java/com/iluwatar/Presentation.java new file mode 100644 index 000000000000..49d6c71a8515 --- /dev/null +++ b/two-step-view/src/main/java/com/iluwatar/Presentation.java @@ -0,0 +1,47 @@ +/* + * This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). + * + * The MIT License + * Copyright © 2014-2022 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; +/** Phase 2.*/ +public class Presentation { + private Presentation() {} + /** Generates an HTML representation of the book details.*/ + public static String presentBook(BookStore bookInStore) { + String newLine = System.lineSeparator(); + return "
" + + newLine + + "

" + bookInStore.getName() + "

" + + newLine + + "

Price: $" + bookInStore.getPrice() + "

" + + newLine + + "

Discounted Price: $" + bookInStore.getDiscountPrice() + "

" + + newLine + + "

Status: " + + (bookInStore.isInStock() ? "In Stock" : "Out of Stock") + + "

" + + newLine + + "
"; + } +} + diff --git a/two-step-view/src/test/java/com/iluwatar/BookStoreTest.java b/two-step-view/src/test/java/com/iluwatar/BookStoreTest.java new file mode 100644 index 000000000000..2e693c016043 --- /dev/null +++ b/two-step-view/src/test/java/com/iluwatar/BookStoreTest.java @@ -0,0 +1,113 @@ +package com.iluwatar; + +import org.junit.Test; + +import static org.junit.Assert.*; + + + +import java.io.ByteArrayOutputStream; +import java.io.PrintStream; +import java.util.logging.Logger; + + +public class BookStoreTest { + + @Test + public void testWithDiscount() { + Book bookWithDiscount = new Book("Superman Vol. 1", 20.00, true, 5); + BookStore bookStoreWithDiscount = DataPreparation.prepareBook(bookWithDiscount); + + assertNotNull(bookStoreWithDiscount); + assertTrue(bookStoreWithDiscount.getName().contains("Superman Vol. 1")); + assertEquals(15.00, bookStoreWithDiscount.getDiscountPrice(), 0.01); + assertTrue(bookStoreWithDiscount.isInStock()); + } + + @Test + public void testWithoutDiscount() { + Book bookWithoutDiscount = new Book("Superman Vol. 1", 20.00, false, 5); + BookStore bookStoreWithoutDiscount = DataPreparation.prepareBook(bookWithoutDiscount); + + assertNotNull(bookStoreWithoutDiscount); + assertTrue(bookStoreWithoutDiscount.getName().contains("Superman Vol. 1")); + assertEquals(20.00, bookStoreWithoutDiscount.getDiscountPrice(), 0.01); + assertTrue(bookStoreWithoutDiscount.isInStock()); + } + + @Test + public void testWithOutOfStock() { + Book bookOutOfStock = new Book("Superman Vol. 1", 20.00, true, 0); + BookStore bookStoreOutOfStock = DataPreparation.prepareBook(bookOutOfStock); + + assertNotNull(bookStoreOutOfStock); + assertTrue(bookStoreOutOfStock.getName().contains("Superman Vol. 1")); + assertEquals(15.00, bookStoreOutOfStock.getDiscountPrice(), 0.01); + assertFalse(bookStoreOutOfStock.isInStock()); + } + + @Test + public void testPrepareZeroPrice() { + Book book = new Book("Zero Price Book", 0.00, true, 5); + BookStore bookStore = DataPreparation.prepareBook(book); + + assertNotNull(bookStore); + assertEquals(0.00, bookStore.getDiscountPrice(), 0.01); + assertTrue(bookStore.isInStock()); + } + + @Test + public void testPrepareNegativeStock() { + Book book = new Book("Negative Stock Book", 10.00, false, -1); + BookStore bookStore = DataPreparation.prepareBook(book); + + assertNotNull(bookStore); + assertFalse(bookStore.isInStock()); + } + + @Test + public void testPresentInStock() { + BookStore bookInStock = new BookStore("Wonder Woman Vol. 1", 15.00, 12.00, true); + String htmlOutput = Presentation.presentBook(bookInStock); + + assertNotNull(htmlOutput); + assertTrue(htmlOutput.contains("

Wonder Woman Vol. 1

")); + assertTrue(htmlOutput.contains("

Price: $15.0

")); + assertTrue(htmlOutput.contains("

Discounted Price: $12.0

")); + assertTrue(htmlOutput.contains("

Status: In Stock

")); + } + + @Test + public void testPresentOutOfStock() { + BookStore bookOutOfStock = new BookStore("Wonder Woman Vol. 1", 15.00, 12.00, false); + String htmlOutput = Presentation.presentBook(bookOutOfStock); + + assertNotNull(htmlOutput); + assertTrue(htmlOutput.contains("

Wonder Woman Vol. 1

")); + assertTrue(htmlOutput.contains("

Price: $15.0

")); + assertTrue(htmlOutput.contains("

Discounted Price: $12.0

")); + assertTrue(htmlOutput.contains("

Status: Out of Stock

")); + } + + @Test + public void testMain() { + // Redirect System.out to capture logger output + ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); + PrintStream printStream = new PrintStream(outputStream); + Logger.getLogger("").addHandler(new java.util.logging.ConsoleHandler() { + { + setOutputStream(printStream); + } + }); + + // Run the main method + App.main(new String[]{}); + + // Check output contains expected HTML + String loggedOutput = outputStream.toString(); + assertTrue(loggedOutput.contains("

Batman Vol. 1: The Court of Owls

")); + assertTrue(loggedOutput.contains("

Price: $11.6

")); + assertTrue(loggedOutput.contains("

Discounted Price: $8.7

")); + assertTrue(loggedOutput.contains("

Status: In Stock

")); + } +} diff --git a/update-header.sh b/update-header.sh index 48da4dcd6125..568d00d52a03 100755 --- a/update-header.sh +++ b/update-header.sh @@ -1,4 +1,29 @@ #!/bin/bash +# +# This project is licensed under the MIT license. Module model-view-viewmodel is using ZK framework licensed under LGPL (see lgpl-3.0.txt). +# +# The MIT License +# Copyright © 2014-2022 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. +# + # Find all README.md files in subdirectories one level deep # and replace "### " with "## " at the beginning of lines