mirror of
https://github.com/tiennm99/java-design-patterns.git
synced 2026-05-25 01:36:48 +00:00
feat: Clean Architecture (#3235)
* #3230 - Clean Architecture. * #3230 - Clean Architecture. * #3230 - Clean Architecture. * #3230 - Clean Architecture. * #3230 - Clean Architecture Sonar. * #3230 - Clean Architecture Sonar. * #3230 - Clean Architecture Sonar. * #3230 - Clean Architecture Sonar. --------- Co-authored-by: Ilkka Seppälä <iluwatar@users.noreply.github.com>
This commit is contained in:
@@ -0,0 +1,52 @@
|
||||
package com.iluwatar.cleanarchitecture;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Clean Architecture ensures separation of concerns by organizing code,
|
||||
* into layers and making it scalable and maintainable.
|
||||
*
|
||||
* <p>In the example there are Entities (Core Models) – Product, Cart,
|
||||
* Order handle business logic.
|
||||
* Use Cases (Application Logic) – ShoppingCartService manages
|
||||
* operations like adding items and checkout.
|
||||
* Interfaces & Adapters – Repositories (CartRepository, OrderRepository)
|
||||
* abstract data handling,
|
||||
* while controllers (CartController, OrderController) manage interactions.
|
||||
*/
|
||||
@Slf4j
|
||||
public final class App {
|
||||
|
||||
private App() {
|
||||
throw new UnsupportedOperationException("Utility class");
|
||||
}
|
||||
|
||||
/**
|
||||
* Program entry point.
|
||||
*
|
||||
* @param args command line args
|
||||
*/
|
||||
public static void main(final String[] args) {
|
||||
ProductRepository productRepository = new InMemoryProductRepository();
|
||||
CartRepository cartRepository = new InMemoryCartRepository();
|
||||
OrderRepository orderRepository = new InMemoryOrderRepository();
|
||||
|
||||
ShoppingCartService
|
||||
shoppingCartUseCase =
|
||||
new ShoppingCartService(
|
||||
productRepository, cartRepository, orderRepository);
|
||||
|
||||
CartController cartController = new CartController(shoppingCartUseCase);
|
||||
OrderController orderController = new OrderController(shoppingCartUseCase);
|
||||
|
||||
String userId = "user123";
|
||||
cartController.addItemToCart(userId, "1", 1);
|
||||
cartController.addItemToCart(userId, "2", 2);
|
||||
|
||||
Order order = orderController.checkout(userId);
|
||||
LOGGER.info("Total: ${}" + cartController.calculateTotal(userId));
|
||||
|
||||
LOGGER.info("Order placed! Order ID: {}, Total: ${}",
|
||||
order.getOrderId(), order.getTotalPrice());
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Represents a shopping cart containing a product and its quantity.
|
||||
* This class calculates the total price of the product based on its price and quantity.
|
||||
*/
|
||||
@Getter
|
||||
public class Cart {
|
||||
/**
|
||||
* The product in the cart.
|
||||
* It holds the product details such as name, price, and description.
|
||||
*/
|
||||
private final Product product;
|
||||
|
||||
/**
|
||||
* The quantity of the product in the cart.
|
||||
* It represents how many units of the product are added to the cart.
|
||||
*/
|
||||
private final int quantity;
|
||||
|
||||
/**
|
||||
* Constructs a new Cart instance with a specified product and quantity.
|
||||
*
|
||||
* @param prod the product to be added to the cart.
|
||||
* @param qty the quantity of the product in the cart.
|
||||
*/
|
||||
public Cart(final Product prod, final int qty) {
|
||||
this.product = prod;
|
||||
this.quantity = qty;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total price of the products in the cart.
|
||||
* The total price is the product's price multiplied by the quantity.
|
||||
*
|
||||
* @return the total price of the products in the cart.
|
||||
*/
|
||||
public double getTotalPrice() {
|
||||
return product.getPrice() * quantity;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
/**
|
||||
* Controller class for handling shopping cart operations.
|
||||
*
|
||||
* <p>This class provides methods to add, remove, and calculate the
|
||||
* total price of items in a user's shopping cart.</p>
|
||||
*/
|
||||
public class CartController {
|
||||
|
||||
|
||||
/** Service layer responsible for cart operations. */
|
||||
private final ShoppingCartService shoppingCartUseCase;
|
||||
|
||||
/**
|
||||
* Constructs a CartController with the specified shopping cart service.
|
||||
*
|
||||
* @param shoppingCart The shopping cart service to handle cart operations.
|
||||
*/
|
||||
public CartController(final ShoppingCartService shoppingCart) {
|
||||
this.shoppingCartUseCase = shoppingCart;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be added.
|
||||
* @param quantity The quantity of the product.
|
||||
*/
|
||||
public void addItemToCart(
|
||||
final String userId, final String productId, final int quantity) {
|
||||
shoppingCartUseCase.addItemToCart(userId, productId, quantity);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be removed.
|
||||
*/
|
||||
public void removeItemFromCart(final String userId, final String productId) {
|
||||
shoppingCartUseCase.removeItemFromCart(userId, productId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total cost of items in the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return The total price of all items in the cart.
|
||||
*/
|
||||
public double calculateTotal(final String userId) {
|
||||
return shoppingCartUseCase.calculateTotal(userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* CartRepository.
|
||||
*/
|
||||
public interface CartRepository {
|
||||
/**
|
||||
* Adds an item to the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param product The product to be added.
|
||||
* @param quantity The quantity of the product.
|
||||
*/
|
||||
void addItemToCart(String userId, Product product, int quantity);
|
||||
/**
|
||||
* Removes an item from the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be removed.
|
||||
*/
|
||||
void removeItemFromCart(String userId, String productId);
|
||||
/**
|
||||
* Retrieves the list of items in the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return A list of items in the cart.
|
||||
*/
|
||||
List<Cart> getItemsInCart(String userId);
|
||||
/**
|
||||
* Calculates the total price of the items in the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return The total price of all items in the cart.
|
||||
*/
|
||||
double calculateTotal(String userId);
|
||||
/**
|
||||
* Clears all items from the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
*/
|
||||
void clearCart(String userId);
|
||||
}
|
||||
+109
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Implementation of {@link CartRepository} that stores cart items in memory.
|
||||
*
|
||||
* <p>This class maintains a map of user carts where each user has a
|
||||
* list of cart items.</p>
|
||||
*/
|
||||
public class InMemoryCartRepository implements CartRepository {
|
||||
/**
|
||||
* A map storing user carts with their respective cart items.
|
||||
*/
|
||||
private final Map<String, List<Cart>> userCarts = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Adds an item to the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param product The product to be added.
|
||||
* @param quantity The quantity of the product.
|
||||
*/
|
||||
@Override
|
||||
public void addItemToCart(
|
||||
final String userId, final Product product, final int quantity) {
|
||||
List<Cart> cart = userCarts.getOrDefault(userId, new ArrayList<>());
|
||||
cart.add(new Cart(product, quantity));
|
||||
userCarts.put(userId, cart);
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes an item from the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be removed.
|
||||
*/
|
||||
@Override
|
||||
public void removeItemFromCart(final String userId, final String productId) {
|
||||
List<Cart> cart = userCarts.get(userId);
|
||||
if (cart != null) {
|
||||
cart.removeIf(item -> item.getProduct().getId().equals(productId));
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves all items in the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return A list of {@link Cart} items in the user's cart.
|
||||
*/
|
||||
@Override
|
||||
public List<Cart> getItemsInCart(final String userId) {
|
||||
return userCarts.getOrDefault(userId, new ArrayList<>());
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total price of items in the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return The total price of the cart.
|
||||
*/
|
||||
@Override
|
||||
public double calculateTotal(final String userId) {
|
||||
return userCarts.getOrDefault(userId, new ArrayList<>())
|
||||
.stream()
|
||||
.mapToDouble(Cart::getTotalPrice)
|
||||
.sum();
|
||||
}
|
||||
|
||||
/**
|
||||
* Clears all items from the user's cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
*/
|
||||
@Override
|
||||
public void clearCart(final String userId) {
|
||||
userCarts.remove(userId);
|
||||
}
|
||||
}
|
||||
+51
@@ -0,0 +1,51 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* An in-memory implementation of the {@link OrderRepository}.
|
||||
*
|
||||
* <p>This class stores orders in a list, allowing orders to be saved
|
||||
* but not persisted beyond the application's runtime.</p>
|
||||
*/
|
||||
public class InMemoryOrderRepository implements OrderRepository {
|
||||
/** A list to store orders in memory. */
|
||||
private final List<Order> orders = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Saves an order to the in-memory repository.
|
||||
*
|
||||
* @param order The order to be saved.
|
||||
*/
|
||||
@Override
|
||||
public void saveOrder(final Order order) {
|
||||
orders.add(order);
|
||||
}
|
||||
}
|
||||
+78
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* In-memory implementation of the {@link ProductRepository} interface.
|
||||
*
|
||||
* <p>This repository stores products in memory
|
||||
* allowing retrieval by product ID.</p>
|
||||
*/
|
||||
public class InMemoryProductRepository implements ProductRepository {
|
||||
/**
|
||||
* A map to store products by their unique product ID.
|
||||
*/
|
||||
private final Map<String, Product> products = new HashMap<>();
|
||||
/**
|
||||
* The price of the Laptop in USD.
|
||||
* <p>Used in the in-memory product repository
|
||||
* to define the cost of a Laptop.</p>
|
||||
*/
|
||||
private static final double LAPTOP_PRICE = 1000.0;
|
||||
|
||||
/**
|
||||
* The price of the Smartphone in USD.
|
||||
* <p>Used in the in-memory product repository
|
||||
* to define the cost of a Smartphone.</p>
|
||||
*/
|
||||
private static final double SMARTPHONE_PRICE = 500.0;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an {@code InMemoryProductRepository} and
|
||||
* initializes it with some example products.
|
||||
*/
|
||||
public InMemoryProductRepository() {
|
||||
products.put("1", new Product("1", "Laptop", LAPTOP_PRICE));
|
||||
products.put("2", new Product("2", "Smartphone", SMARTPHONE_PRICE));
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieves a product by its unique ID.
|
||||
*
|
||||
* @param productId The ID of the product to retrieve.
|
||||
* @return The {@link Product} corresponding to the given ID
|
||||
* {@code null} if not found.
|
||||
*/
|
||||
@Override
|
||||
public Product getProductById(final String productId) {
|
||||
return products.get(productId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Represents an order placed by a user containing
|
||||
* the ordered items and total price.
|
||||
*
|
||||
* <p>An order includes a unique order ID, a list of cart items
|
||||
* and the total price of the order.</p>
|
||||
*/
|
||||
@Getter
|
||||
public class Order {
|
||||
/**
|
||||
* The unique identifier for this order.
|
||||
*/
|
||||
private final String orderId;
|
||||
/**
|
||||
* The list of items included in this order.
|
||||
*/
|
||||
private final List<Cart> items;
|
||||
/**
|
||||
* The list of items included in this order.
|
||||
*/
|
||||
private final double totalPrice;
|
||||
|
||||
/**
|
||||
* Constructs an {@code Order} with the given order ID and list of cart items.
|
||||
* The total price is based on the individual item prices in the cart.
|
||||
*
|
||||
* @param id The unique identifier for the order.
|
||||
* @param item The list of cart items included in the order.
|
||||
*/
|
||||
public Order(final String id, final List<Cart> item) {
|
||||
this.orderId = id;
|
||||
this.items = item;
|
||||
this.totalPrice = items.stream().mapToDouble(Cart::getTotalPrice).sum();
|
||||
}
|
||||
}
|
||||
@@ -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.cleanarchitecture;
|
||||
|
||||
/**
|
||||
* Controller for handling order-related operations.
|
||||
*
|
||||
* <p>This class provides an endpoint for users to checkout their cart
|
||||
* and place an order.</p>
|
||||
*/
|
||||
public class OrderController {
|
||||
/**
|
||||
* Service for managing shopping cart operations.
|
||||
*/
|
||||
private final ShoppingCartService shoppingCartUseCase;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs an {@code OrderController} with the given shopping cart service.
|
||||
*
|
||||
* @param shoppingCartUse The shopping cart service used to process orders.
|
||||
*/
|
||||
public OrderController(final ShoppingCartService shoppingCartUse) {
|
||||
this.shoppingCartUseCase = shoppingCartUse;
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes the checkout for a given user and creates an order.
|
||||
*
|
||||
* @param userId The ID of the user checking out.
|
||||
* @return The created {@link Order} after checkout.
|
||||
*/
|
||||
public Order checkout(final String userId) {
|
||||
return shoppingCartUseCase.checkout(userId);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
/**
|
||||
* Repository interface for managing order persistence.
|
||||
*
|
||||
* <p>This interface defines the contract for storing orders in the system.</p>
|
||||
*/
|
||||
public interface OrderRepository {
|
||||
/**
|
||||
* Saves an order to the repository.
|
||||
*
|
||||
* @param order The order to be saved.
|
||||
*/
|
||||
void saveOrder(Order order);
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
/**
|
||||
* Represents a product in the system.
|
||||
*/
|
||||
@Getter
|
||||
public class Product {
|
||||
/** The unique identifier for the product. */
|
||||
private final String id;
|
||||
|
||||
/** The name of the product. */
|
||||
private final String name;
|
||||
|
||||
/** The price of the product. */
|
||||
private final double price;
|
||||
|
||||
/**
|
||||
* Constructs a new Product with the given details.
|
||||
*
|
||||
* @param pdtId The unique identifier of the product.
|
||||
* @param firstName The name of the product.
|
||||
* @param p The price of the product.
|
||||
*/
|
||||
public Product(final String pdtId, final String firstName, final double p) {
|
||||
this.id = pdtId;
|
||||
this.name = firstName;
|
||||
this.price = p;
|
||||
}
|
||||
}
|
||||
+40
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
/**
|
||||
* Repository interface for handling product-related operations.
|
||||
*/
|
||||
public interface ProductRepository {
|
||||
/**
|
||||
* Retrieves a product by its unique identifier.
|
||||
*
|
||||
* @param productId The unique ID of the product.
|
||||
* @return The product corresponding to the given ID.
|
||||
*/
|
||||
Product getProductById(String productId);
|
||||
}
|
||||
+112
@@ -0,0 +1,112 @@
|
||||
/*
|
||||
* 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.cleanarchitecture;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
* Service class for managing shopping cart operations.
|
||||
*
|
||||
* <p>This class provides functionalities to add and remove items from the cart,
|
||||
* calculate the total price, and handle checkout operations.</p>
|
||||
*/
|
||||
public class ShoppingCartService {
|
||||
/** Repository for managing product data. */
|
||||
private final ProductRepository productRepository;
|
||||
/** Repository for managing cart data. */
|
||||
private final CartRepository cartRepository;
|
||||
/** Repository for managing order data. */
|
||||
private final OrderRepository orderRepository;
|
||||
|
||||
|
||||
/**
|
||||
* Constructs a ShoppingCartService with the required repositories.
|
||||
*
|
||||
* @param pdtRepository The repository to fetch product details.
|
||||
* @param repository The repository to manage cart operations.
|
||||
* @param ordRepository The repository to handle order persistence.
|
||||
*/
|
||||
public ShoppingCartService(final ProductRepository pdtRepository,
|
||||
final CartRepository repository,
|
||||
final OrderRepository ordRepository) {
|
||||
this.productRepository = pdtRepository;
|
||||
this.cartRepository = repository;
|
||||
this.orderRepository = ordRepository;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds an item to the user's shopping cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be added.
|
||||
* @param quantity The quantity of the product.
|
||||
*/
|
||||
public void addItemToCart(
|
||||
final String userId, final String productId, final int quantity) {
|
||||
Product product = productRepository.getProductById(productId);
|
||||
if (product != null) {
|
||||
cartRepository.addItemToCart(userId, product, quantity);
|
||||
}
|
||||
}
|
||||
/**
|
||||
* Removes an item from the user's shopping cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @param productId The ID of the product to be removed.
|
||||
*/
|
||||
public void removeItemFromCart(final String userId, final String productId) {
|
||||
cartRepository.removeItemFromCart(userId, productId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates the total cost of items in the user's shopping cart.
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return The total price of all items in the cart.
|
||||
*/
|
||||
public double calculateTotal(final String userId) {
|
||||
return cartRepository.calculateTotal(userId);
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks out the user's cart and creates an order.
|
||||
*
|
||||
* <p>This method retrieves the cart items, generates an order ID,
|
||||
* creates a new order, saves it, and clears the cart.</p>
|
||||
*
|
||||
* @param userId The ID of the user.
|
||||
* @return The created order containing purchased items.
|
||||
*/
|
||||
public Order checkout(final String userId) {
|
||||
List<Cart> items = cartRepository.getItemsInCart(userId);
|
||||
String orderId = "ORDER-" + System.currentTimeMillis();
|
||||
Order order = new Order(orderId, items);
|
||||
orderRepository.saveOrder(order);
|
||||
cartRepository.clearCart(userId);
|
||||
return order;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
/**
|
||||
* Provides classes and interfaces for the clean architecture
|
||||
* pattern implementation.
|
||||
*
|
||||
* <p>This package includes classes for managing products, carts,
|
||||
* orders, repositories,
|
||||
* and services for a shopping cart system, following the
|
||||
* clean architecture principles.</p>
|
||||
*/
|
||||
package com.iluwatar.cleanarchitecture;
|
||||
@@ -0,0 +1,20 @@
|
||||
package com.iluwatar.cleanarchitecture;
|
||||
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.junit.jupiter.api.Assertions.*;
|
||||
|
||||
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}
|
||||
* throws an exception.
|
||||
*/
|
||||
|
||||
@Test
|
||||
void shouldExecuteApplicationWithoutException() {
|
||||
|
||||
assertDoesNotThrow(() -> App.main(new String[]{}));
|
||||
}
|
||||
}
|
||||
+41
@@ -0,0 +1,41 @@
|
||||
package com.iluwatar.cleanarchitecture;
|
||||
|
||||
import org.junit.jupiter.api.BeforeEach;
|
||||
import org.junit.jupiter.api.Test;
|
||||
import static org.junit.jupiter.api.Assertions.assertEquals;
|
||||
|
||||
|
||||
public class CartControllerTest {
|
||||
|
||||
private ShoppingCartService shoppingCartUseCase;
|
||||
private CartController cartController;
|
||||
|
||||
@BeforeEach
|
||||
public void setUp() {
|
||||
ProductRepository productRepository = new InMemoryProductRepository();
|
||||
CartRepository cartRepository = new InMemoryCartRepository();
|
||||
OrderRepository orderRepository = new InMemoryOrderRepository();
|
||||
shoppingCartUseCase = new ShoppingCartService(productRepository, cartRepository, orderRepository);
|
||||
cartController = new CartController(shoppingCartUseCase);
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveItemFromCart() {
|
||||
cartController.addItemToCart("user123", "1", 1);
|
||||
cartController.addItemToCart("user123", "2", 2);
|
||||
|
||||
assertEquals(2000.0, cartController.calculateTotal("user123"));
|
||||
|
||||
cartController.removeItemFromCart("user123", "1");
|
||||
|
||||
assertEquals(1000.0, cartController.calculateTotal("user123"));
|
||||
}
|
||||
|
||||
@Test
|
||||
void testRemoveNonExistentItem() {
|
||||
cartController.addItemToCart("user123", "2", 2);
|
||||
cartController.removeItemFromCart("user123", "999");
|
||||
|
||||
assertEquals(1000.0, cartController.calculateTotal("user123"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user