monolithic-architecture/README.md
Encapsulate all the functionality of an application within a single, cohesive codebase.
Real-world example
An analogous real-world example of the Monolithic Architecture pattern is a department store. Just like a monolithic Java application, a department store hosts all product categories, sales, storage, and customer services within a single, large building. It simplifies shopping by consolidating everything under one roof, making operations straightforward and easy to manage. However, expanding or rearranging specific departments becomes increasingly challenging over time, similar to how scaling individual functionalities within a monolithic system can become complex and cumbersome.
In plain words
The monolithic design pattern structures an application as a single unified unit, where all components are tightly coupled and run within a single process.
Wikipedia says
In software engineering, a monolithic application is a single unified software application that is self-contained and independent of other applications, but typically lacks flexibility. There are advantages and disadvantages of building applications in a monolithic style of software architecture, depending on requirements. Monolith applications are relatively simple and have a low cost but their shortcomings are lack of elasticity, fault tolerance and scalability.
Mind map
Flowchart
This is a simplified version of the main application, demonstrating how a monolithic architecture can be implemented. Here, all the essential services—such as user management (UserCon), product management (ProductCon), and order processing (OrderCon) — are tightly integrated within a single executable Java application. The CLI provides a straightforward user interaction point where operations like user registration, adding products, and placing orders are handled.
@SpringBootApplication
public class EcommerceApp implements CommandLineRunner {
private static final Logger log = LogManager.getLogger(EcommerceApp.class);
private final UserCon userService;
private final ProductCon productService;
private final OrderCon orderService;
public EcommerceApp(UserCon userService, ProductCon productService, OrderCon orderService) {
this.userService = userService;
this.productService = productService;
this.orderService = orderService;
}
public static void main(String... args) {
SpringApplication.run(EcommerceApp.class, args);
}
@Override
public void run(String... args) {
Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8);
log.info("Welcome to the Monolithic E-commerce CLI!");
while (true) {
log.info("\nChoose an option:");
log.info("1. Register User");
log.info("2. Add Product");
log.info("3. Place Order");
log.info("4. Exit");
log.info("Enter your choice: ");
int userInput = scanner.nextInt();
scanner.nextLine();
switch (userInput) {
case 1 -> registerUser(scanner);
case 2 -> addProduct(scanner);
case 3 -> placeOrder(scanner);
case 4 -> {
log.info("Exiting the application. Goodbye!");
return;
}
default -> log.info("Invalid choice! Please try again.");
}
}
}
protected void registerUser(Scanner scanner) {
log.info("Enter user details:");
log.info("Name: ");
String name = scanner.nextLine();
log.info("Email: ");
String email = scanner.nextLine();
log.info("Password: ");
String password = scanner.nextLine();
User user = new User(null, name, email, password);
userService.registerUser(user);
log.info("User registered successfully!");
}
}
In this example, the core business functionalities are closely interconnected, sharing common resources and residing within the same codebase. This approach simplifies initial application development, testing, and deployment, as each component can easily access the others directly without the overhead of inter-service communication. However, as the application grows, scaling individual components independently becomes more challenging, highlighting the key trade-off inherent in the monolithic architecture.
Benefits:
Trade-offs: