fix: clean-architecture logging deps and spotless formatting

This commit is contained in:
Ilkka Seppälä committed 2025-04-05 09:48:15 +03:00
1 parent ee699af6ef
commit 356db48c8e
17 files changed
+90 -116

No files matched your search

+8
View File
@@ -39,6 +39,14 @@
<artifactId>junit-jupiter-engine</artifactId> <artifactId>junit-jupiter-engine</artifactId>
<scope>test</scope> <scope>test</scope>
</dependency> </dependency>
<dependency>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-api</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
</dependencies> </dependencies>
<build> <build>
<plugins> <plugins>
@@ -3,16 +3,13 @@ package com.iluwatar.cleanarchitecture;
import lombok.extern.slf4j.Slf4j; import lombok.extern.slf4j.Slf4j;
/** /**
* Clean Architecture ensures separation of concerns by organizing code, * Clean Architecture ensures separation of concerns by organizing code, into layers and making it
* into layers and making it scalable and maintainable. * scalable and maintainable.
* *
* <p>In the example there are Entities (Core Models) – Product, Cart, * <p>In the example there are Entities (Core Models) – Product, Cart, Order handle business logic.
* Order handle business logic. * Use Cases (Application Logic) – ShoppingCartService manages operations like adding items and
* Use Cases (Application Logic) – ShoppingCartService manages * checkout. Interfaces & Adapters – Repositories (CartRepository, OrderRepository) abstract data
* operations like adding items and checkout. * handling, while controllers (CartController, OrderController) manage interactions.
* Interfaces & Adapters – Repositories (CartRepository, OrderRepository)
* abstract data handling,
* while controllers (CartController, OrderController) manage interactions.
*/ */
@Slf4j @Slf4j
public final class App { public final class App {
@@ -31,10 +28,8 @@ public final class App {
CartRepository cartRepository = new InMemoryCartRepository(); CartRepository cartRepository = new InMemoryCartRepository();
OrderRepository orderRepository = new InMemoryOrderRepository(); OrderRepository orderRepository = new InMemoryOrderRepository();
ShoppingCartService ShoppingCartService shoppingCartUseCase =
shoppingCartUseCase = new ShoppingCartService(productRepository, cartRepository, orderRepository);
new ShoppingCartService(
productRepository, cartRepository, orderRepository);
CartController cartController = new CartController(shoppingCartUseCase); CartController cartController = new CartController(shoppingCartUseCase);
OrderController orderController = new OrderController(shoppingCartUseCase); OrderController orderController = new OrderController(shoppingCartUseCase);
@@ -46,7 +41,7 @@ public final class App {
Order order = orderController.checkout(userId); Order order = orderController.checkout(userId);
LOGGER.info("Total: ${}" + cartController.calculateTotal(userId)); LOGGER.info("Total: ${}" + cartController.calculateTotal(userId));
LOGGER.info("Order placed! Order ID: {}, Total: ${}", LOGGER.info(
order.getOrderId(), order.getTotalPrice()); "Order placed! Order ID: {}, Total: ${}", order.getOrderId(), order.getTotalPrice());
} }
} }
@@ -29,20 +29,17 @@ package com.iluwatar.cleanarchitecture;
import lombok.Getter; import lombok.Getter;
/** /**
* Represents a shopping cart containing a product and its quantity. * Represents a shopping cart containing a product and its quantity. This class calculates the total
* This class calculates the total price of the product based on its price and quantity. * price of the product based on its price and quantity.
*/ */
@Getter @Getter
public class Cart { public class Cart {
/** /** The product in the cart. It holds the product details such as name, price, and description. */
* The product in the cart.
* It holds the product details such as name, price, and description.
*/
private final Product product; private final Product product;
/** /**
* The quantity of the product in the cart. * The quantity of the product in the cart. It represents how many units of the product are added
* It represents how many units of the product are added to the cart. * to the cart.
*/ */
private final int quantity; private final int quantity;
@@ -58,13 +55,12 @@ public class Cart {
} }
/** /**
* Calculates the total price of the products in the cart. * Calculates the total price of the products in the cart. The total price is the product's price
* The total price is the product's price multiplied by the quantity. * multiplied by the quantity.
* *
* @return the total price of the products in the cart. * @return the total price of the products in the cart.
*/ */
public double getTotalPrice() { public double getTotalPrice() {
return product.getPrice() * quantity; return product.getPrice() * quantity;
} }
} }
@@ -30,12 +30,11 @@ package com.iluwatar.cleanarchitecture;
/** /**
* Controller class for handling shopping cart operations. * Controller class for handling shopping cart operations.
* *
* <p>This class provides methods to add, remove, and calculate the * <p>This class provides methods to add, remove, and calculate the total price of items in a user's
* total price of items in a user's shopping cart.</p> * shopping cart.
*/ */
public class CartController { public class CartController {
/** Service layer responsible for cart operations. */ /** Service layer responsible for cart operations. */
private final ShoppingCartService shoppingCartUseCase; private final ShoppingCartService shoppingCartUseCase;
@@ -55,8 +54,7 @@ public class CartController {
* @param productId The ID of the product to be added. * @param productId The ID of the product to be added.
* @param quantity The quantity of the product. * @param quantity The quantity of the product.
*/ */
public void addItemToCart( public void addItemToCart(final String userId, final String productId, final int quantity) {
final String userId, final String productId, final int quantity) {
shoppingCartUseCase.addItemToCart(userId, productId, quantity); shoppingCartUseCase.addItemToCart(userId, productId, quantity);
} }
@@ -28,9 +28,7 @@ package com.iluwatar.cleanarchitecture;
import java.util.List; import java.util.List;
/** /** CartRepository. */
* CartRepository.
*/
public interface CartRepository { public interface CartRepository {
/** /**
* Adds an item to the user's cart. * Adds an item to the user's cart.
@@ -40,6 +38,7 @@ public interface CartRepository {
* @param quantity The quantity of the product. * @param quantity The quantity of the product.
*/ */
void addItemToCart(String userId, Product product, int quantity); void addItemToCart(String userId, Product product, int quantity);
/** /**
* Removes an item from the user's cart. * Removes an item from the user's cart.
* *
@@ -47,6 +46,7 @@ public interface CartRepository {
* @param productId The ID of the product to be removed. * @param productId The ID of the product to be removed.
*/ */
void removeItemFromCart(String userId, String productId); void removeItemFromCart(String userId, String productId);
/** /**
* Retrieves the list of items in the user's cart. * Retrieves the list of items in the user's cart.
* *
@@ -54,6 +54,7 @@ public interface CartRepository {
* @return A list of items in the cart. * @return A list of items in the cart.
*/ */
List<Cart> getItemsInCart(String userId); List<Cart> getItemsInCart(String userId);
/** /**
* Calculates the total price of the items in the user's cart. * Calculates the total price of the items in the user's cart.
* *
@@ -61,6 +62,7 @@ public interface CartRepository {
* @return The total price of all items in the cart. * @return The total price of all items in the cart.
*/ */
double calculateTotal(String userId); double calculateTotal(String userId);
/** /**
* Clears all items from the user's cart. * Clears all items from the user's cart.
* *
@@ -34,25 +34,21 @@ import java.util.Map;
/** /**
* Implementation of {@link CartRepository} that stores cart items in memory. * Implementation of {@link CartRepository} that stores cart items in memory.
* *
* <p>This class maintains a map of user carts where each user has a * <p>This class maintains a map of user carts where each user has a list of cart items.
* list of cart items.</p>
*/ */
public class InMemoryCartRepository implements CartRepository { public class InMemoryCartRepository implements CartRepository {
/** /** A map storing user carts with their respective cart items. */
* A map storing user carts with their respective cart items.
*/
private final Map<String, List<Cart>> userCarts = new HashMap<>(); private final Map<String, List<Cart>> userCarts = new HashMap<>();
/** /**
* Adds an item to the user's cart. * Adds an item to the user's cart.
* *
* @param userId The ID of the user. * @param userId The ID of the user.
* @param product The product to be added. * @param product The product to be added.
* @param quantity The quantity of the product. * @param quantity The quantity of the product.
*/ */
@Override @Override
public void addItemToCart( public void addItemToCart(final String userId, final Product product, final int quantity) {
final String userId, final Product product, final int quantity) {
List<Cart> cart = userCarts.getOrDefault(userId, new ArrayList<>()); List<Cart> cart = userCarts.getOrDefault(userId, new ArrayList<>());
cart.add(new Cart(product, quantity)); cart.add(new Cart(product, quantity));
userCarts.put(userId, cart); userCarts.put(userId, cart);
@@ -91,8 +87,7 @@ public class InMemoryCartRepository implements CartRepository {
*/ */
@Override @Override
public double calculateTotal(final String userId) { public double calculateTotal(final String userId) {
return userCarts.getOrDefault(userId, new ArrayList<>()) return userCarts.getOrDefault(userId, new ArrayList<>()).stream()
.stream()
.mapToDouble(Cart::getTotalPrice) .mapToDouble(Cart::getTotalPrice)
.sum(); .sum();
} }
@@ -32,8 +32,8 @@ import java.util.List;
/** /**
* An in-memory implementation of the {@link OrderRepository}. * An in-memory implementation of the {@link OrderRepository}.
* *
* <p>This class stores orders in a list, allowing orders to be saved * <p>This class stores orders in a list, allowing orders to be saved but not persisted beyond the
* but not persisted beyond the application's runtime.</p> * application's runtime.
*/ */
public class InMemoryOrderRepository implements OrderRepository { public class InMemoryOrderRepository implements OrderRepository {
/** A list to store orders in memory. */ /** A list to store orders in memory. */
@@ -32,32 +32,28 @@ import java.util.Map;
/** /**
* In-memory implementation of the {@link ProductRepository} interface. * In-memory implementation of the {@link ProductRepository} interface.
* *
* <p>This repository stores products in memory * <p>This repository stores products in memory allowing retrieval by product ID.
* allowing retrieval by product ID.</p>
*/ */
public class InMemoryProductRepository implements ProductRepository { public class InMemoryProductRepository implements ProductRepository {
/** /** A map to store products by their unique product ID. */
* A map to store products by their unique product ID.
*/
private final Map<String, Product> products = new HashMap<>(); private final Map<String, Product> products = new HashMap<>();
/** /**
* The price of the Laptop in USD. * The price of the Laptop in USD.
* <p>Used in the in-memory product repository *
* to define the cost of a Laptop.</p> * <p>Used in the in-memory product repository to define the cost of a Laptop.
*/ */
private static final double LAPTOP_PRICE = 1000.0; private static final double LAPTOP_PRICE = 1000.0;
/** /**
* The price of the Smartphone in USD. * The price of the Smartphone in USD.
* <p>Used in the in-memory product repository *
* to define the cost of a Smartphone.</p> * <p>Used in the in-memory product repository to define the cost of a Smartphone.
*/ */
private static final double SMARTPHONE_PRICE = 500.0; private static final double SMARTPHONE_PRICE = 500.0;
/** /**
* Constructs an {@code InMemoryProductRepository} and * Constructs an {@code InMemoryProductRepository} and initializes it with some example products.
* initializes it with some example products.
*/ */
public InMemoryProductRepository() { public InMemoryProductRepository() {
products.put("1", new Product("1", "Laptop", LAPTOP_PRICE)); products.put("1", new Product("1", "Laptop", LAPTOP_PRICE));
@@ -68,8 +64,7 @@ public class InMemoryProductRepository implements ProductRepository {
* Retrieves a product by its unique ID. * Retrieves a product by its unique ID.
* *
* @param productId The ID of the product to retrieve. * @param productId The ID of the product to retrieve.
* @return The {@link Product} corresponding to the given ID * @return The {@link Product} corresponding to the given ID {@code null} if not found.
* {@code null} if not found.
*/ */
@Override @Override
public Product getProductById(final String productId) { public Product getProductById(final String productId) {
@@ -30,33 +30,27 @@ import java.util.List;
import lombok.Getter; import lombok.Getter;
/** /**
* Represents an order placed by a user containing * Represents an order placed by a user containing the ordered items and total price.
* the ordered items and total price.
* *
* <p>An order includes a unique order ID, a list of cart items * <p>An order includes a unique order ID, a list of cart items and the total price of the order.
* and the total price of the order.</p>
*/ */
@Getter @Getter
public class Order { public class Order {
/** /** The unique identifier for this order. */
* The unique identifier for this order.
*/
private final String orderId; private final String orderId;
/**
* The list of items included in this order. /** The list of items included in this order. */
*/
private final List<Cart> items; private final List<Cart> items;
/**
* The list of items included in this order. /** The list of items included in this order. */
*/
private final double totalPrice; private final double totalPrice;
/** /**
* Constructs an {@code Order} with the given order ID and list of cart items. * Constructs an {@code Order} with the given order ID and list of cart items. The total price is
* The total price is based on the individual item prices in the cart. * based on the individual item prices in the cart.
* *
* @param id The unique identifier for the order. * @param id The unique identifier for the order.
* @param item The list of cart items included in the order. * @param item The list of cart items included in the order.
*/ */
public Order(final String id, final List<Cart> item) { public Order(final String id, final List<Cart> item) {
this.orderId = id; this.orderId = id;
@@ -29,16 +29,12 @@ package com.iluwatar.cleanarchitecture;
/** /**
* Controller for handling order-related operations. * Controller for handling order-related operations.
* *
* <p>This class provides an endpoint for users to checkout their cart * <p>This class provides an endpoint for users to checkout their cart and place an order.
* and place an order.</p>
*/ */
public class OrderController { public class OrderController {
/** /** Service for managing shopping cart operations. */
* Service for managing shopping cart operations.
*/
private final ShoppingCartService shoppingCartUseCase; private final ShoppingCartService shoppingCartUseCase;
/** /**
* Constructs an {@code OrderController} with the given shopping cart service. * Constructs an {@code OrderController} with the given shopping cart service.
* *
@@ -29,7 +29,7 @@ package com.iluwatar.cleanarchitecture;
/** /**
* Repository interface for managing order persistence. * Repository interface for managing order persistence.
* *
* <p>This interface defines the contract for storing orders in the system.</p> * <p>This interface defines the contract for storing orders in the system.
*/ */
public interface OrderRepository { public interface OrderRepository {
/** /**
@@ -28,9 +28,7 @@ package com.iluwatar.cleanarchitecture;
import lombok.Getter; import lombok.Getter;
/** /** Represents a product in the system. */
* Represents a product in the system.
*/
@Getter @Getter
public class Product { public class Product {
/** The unique identifier for the product. */ /** The unique identifier for the product. */
@@ -26,9 +26,7 @@
*/ */
package com.iluwatar.cleanarchitecture; package com.iluwatar.cleanarchitecture;
/** /** Repository interface for handling product-related operations. */
* Repository interface for handling product-related operations.
*/
public interface ProductRepository { public interface ProductRepository {
/** /**
* Retrieves a product by its unique identifier. * Retrieves a product by its unique identifier.
@@ -31,18 +31,19 @@ import java.util.List;
/** /**
* Service class for managing shopping cart operations. * Service class for managing shopping cart operations.
* *
* <p>This class provides functionalities to add and remove items from the cart, * <p>This class provides functionalities to add and remove items from the cart, calculate the total
* calculate the total price, and handle checkout operations.</p> * price, and handle checkout operations.
*/ */
public class ShoppingCartService { public class ShoppingCartService {
/** Repository for managing product data. */ /** Repository for managing product data. */
private final ProductRepository productRepository; private final ProductRepository productRepository;
/** Repository for managing cart data. */ /** Repository for managing cart data. */
private final CartRepository cartRepository; private final CartRepository cartRepository;
/** Repository for managing order data. */ /** Repository for managing order data. */
private final OrderRepository orderRepository; private final OrderRepository orderRepository;
/** /**
* Constructs a ShoppingCartService with the required repositories. * Constructs a ShoppingCartService with the required repositories.
* *
@@ -50,9 +51,10 @@ public class ShoppingCartService {
* @param repository The repository to manage cart operations. * @param repository The repository to manage cart operations.
* @param ordRepository The repository to handle order persistence. * @param ordRepository The repository to handle order persistence.
*/ */
public ShoppingCartService(final ProductRepository pdtRepository, public ShoppingCartService(
final CartRepository repository, final ProductRepository pdtRepository,
final OrderRepository ordRepository) { final CartRepository repository,
final OrderRepository ordRepository) {
this.productRepository = pdtRepository; this.productRepository = pdtRepository;
this.cartRepository = repository; this.cartRepository = repository;
this.orderRepository = ordRepository; this.orderRepository = ordRepository;
@@ -65,13 +67,13 @@ public class ShoppingCartService {
* @param productId The ID of the product to be added. * @param productId The ID of the product to be added.
* @param quantity The quantity of the product. * @param quantity The quantity of the product.
*/ */
public void addItemToCart( public void addItemToCart(final String userId, final String productId, final int quantity) {
final String userId, final String productId, final int quantity) {
Product product = productRepository.getProductById(productId); Product product = productRepository.getProductById(productId);
if (product != null) { if (product != null) {
cartRepository.addItemToCart(userId, product, quantity); cartRepository.addItemToCart(userId, product, quantity);
} }
} }
/** /**
* Removes an item from the user's shopping cart. * Removes an item from the user's shopping cart.
* *
@@ -95,8 +97,8 @@ public class ShoppingCartService {
/** /**
* Checks out the user's cart and creates an order. * Checks out the user's cart and creates an order.
* *
* <p>This method retrieves the cart items, generates an order ID, * <p>This method retrieves the cart items, generates an order ID, creates a new order, saves it,
* creates a new order, saves it, and clears the cart.</p> * and clears the cart.
* *
* @param userId The ID of the user. * @param userId The ID of the user.
* @return The created order containing purchased items. * @return The created order containing purchased items.
@@ -1,10 +1,7 @@
/** /**
* Provides classes and interfaces for the clean architecture * Provides classes and interfaces for the clean architecture pattern implementation.
* pattern implementation.
* *
* <p>This package includes classes for managing products, carts, * <p>This package includes classes for managing products, carts, orders, repositories, and services
* orders, repositories, * for a shopping cart system, following the clean architecture principles.
* and services for a shopping cart system, following the
* clean architecture principles.</p>
*/ */
package com.iluwatar.cleanarchitecture; package com.iluwatar.cleanarchitecture;
@@ -1,20 +1,19 @@
package com.iluwatar.cleanarchitecture; package com.iluwatar.cleanarchitecture;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*; import static org.junit.jupiter.api.Assertions.*;
import org.junit.jupiter.api.Test;
class AppTest { class AppTest {
/** /**
* Issue: Add at least one assertion to this test case. * 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} * <p>Solution: Inserted assertion to check whether the execution of the main method in {@link
* throws an exception. * App} throws an exception.
*/ */
@Test @Test
void shouldExecuteApplicationWithoutException() { void shouldExecuteApplicationWithoutException() {
assertDoesNotThrow(() -> App.main(new String[]{})); assertDoesNotThrow(() -> App.main(new String[] {}));
} }
} }
@@ -1,9 +1,9 @@
package com.iluwatar.cleanarchitecture; package com.iluwatar.cleanarchitecture;
import static org.junit.jupiter.api.Assertions.assertEquals;
import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test; import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.assertEquals;
public class CartControllerTest { public class CartControllerTest {
@@ -15,7 +15,8 @@ public class CartControllerTest {
ProductRepository productRepository = new InMemoryProductRepository(); ProductRepository productRepository = new InMemoryProductRepository();
CartRepository cartRepository = new InMemoryCartRepository(); CartRepository cartRepository = new InMemoryCartRepository();
OrderRepository orderRepository = new InMemoryOrderRepository(); OrderRepository orderRepository = new InMemoryOrderRepository();
shoppingCartUseCase = new ShoppingCartService(productRepository, cartRepository, orderRepository); shoppingCartUseCase =
new ShoppingCartService(productRepository, cartRepository, orderRepository);
cartController = new CartController(shoppingCartUseCase); cartController = new CartController(shoppingCartUseCase);
} }
@@ -38,4 +39,4 @@ public class CartControllerTest {
assertEquals(1000.0, cartController.calculateTotal("user123")); assertEquals(1000.0, cartController.calculateTotal("user123"));
} }
} }