Skip to content

Commit 5b03784

Browse files
author
Mohaned Atef
committed
Fixes
Renamed the main module/directory. Added more content to the readme.md file. fixed the orElseThrow statements Fixes Renamed the main module/directory. Added more content to the readme.md file. fixed the orElseThrow statements
1 parent ef03a2c commit 5b03784

File tree

20 files changed

+362
-14
lines changed

20 files changed

+362
-14
lines changed

monolithic-architecture/README.md

Lines changed: 136 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,136 @@
1+
## Monolithic-Ecommerce App
2+
* A Monolithic Ecommerce example to showcase Monolithic Architecture
3+
4+
## The Intent of Monolithic Design pattern
5+
> the Monolithic Design Pattern structures an application as a single, cohesive unit where all components—such as business logic, user interface, and data access are tightly integrated and operate as part of a single executable.
6+
7+
## Detailed Explanation of the Monolithic Architecture
8+
Real-world Example
9+
> A traditional E-commerce website is the most straightforward example for a monolithic application as it is comprised of a catalogue of products, orders to be made, shopping carts, and payment processes that are all inseperable of each other.
10+
11+
In Plain words
12+
>The monolithic design pattern structures an application as a single unified unit, where all components are tightly coupled and run within a single process.
13+
14+
GeeksforGeeks states
15+
> Monolithic architecture, a traditional approach in system design, which contains all application components into a single codebase. This unified structure simplifies development and deployment processes, offering ease of management and tight integration. However, because of its rigidity, it is difficult to scale and maintain, which makes it difficult to adjust to changing needs.
16+
17+
Why use MVC for a Monolithic Application ?
18+
>The Model-View-Controller (MVC) pattern is not inherently tied to microservices or distributed systems. It's a software design pattern that organizes the codebase by separating concerns into three distinct layers:
19+
>* Model
20+
>* View
21+
>* Controller
22+
>
23+
> this also helps maintain the principles of a Monolithic Architecture which are:
24+
>
25+
> Simple to
26+
>* Develop
27+
>* Test
28+
>* Deploy
29+
>* Scale
30+
>
31+
## We can clearly see that this is a Monolithic application through the main class
32+
This is a simplified version of the main application that shows the main interaction point with the CLI and how a user is registered
33+
```java
34+
@SpringBootApplication
35+
public class EcommerceApp implements CommandLineRunner {
36+
37+
private static final Logger log = LogManager.getLogger(EcommerceApp.class);
38+
private final UserCon userService;
39+
private final ProductCon productService;
40+
private final OrderCon orderService;
41+
public EcommerceApp(UserCon userService, ProductCon productService, OrderCon orderService) {
42+
this.userService = userService;
43+
this.productService = productService;
44+
this.orderService = orderService;
45+
}
46+
public static void main(String... args) {
47+
SpringApplication.run(EcommerceApp.class, args);
48+
}
49+
@Override
50+
public void run(String... args) {
51+
Scanner scanner = new Scanner(System.in, StandardCharsets.UTF_8);
52+
53+
log.info("Welcome to the Monolithic E-commerce CLI!");
54+
while (true) {
55+
log.info("\nChoose an option:");
56+
log.info("1. Register User");
57+
log.info("2. Add Product");
58+
log.info("3. Place Order");
59+
log.info("4. Exit");
60+
log.info("Enter your choice: ");
61+
62+
int userInput = scanner.nextInt();
63+
scanner.nextLine();
64+
65+
switch (userInput) {
66+
case 1 -> registerUser(scanner);
67+
case 2 -> addProduct(scanner);
68+
case 3 -> placeOrder(scanner);
69+
case 4 -> {
70+
log.info("Exiting the application. Goodbye!");
71+
return;
72+
}
73+
default -> log.info("Invalid choice! Please try again.");
74+
}
75+
}
76+
}
77+
protected void registerUser(Scanner scanner) {
78+
log.info("Enter user details:");
79+
log.info("Name: ");
80+
String name = scanner.nextLine();
81+
log.info("Email: ");
82+
String email = scanner.nextLine();
83+
log.info("Password: ");
84+
String password = scanner.nextLine();
85+
86+
User user = new User(null, name, email, password);
87+
userService.registerUser(user);
88+
log.info("User registered successfully!");
89+
}
90+
91+
}
92+
```
93+
### We can clearly reach the conclusion that all of these classes reside under the same module and are essential for each other's functionality, this is supported by the presence of all relevant classes as parts of the main application class.
94+
95+
## When should you resort to a Monolithic Architecture ?
96+
>* An enterprise Starting off with a relatively small team
97+
>* Simplicity is the most important factor of the project
98+
>* Maintaining less entry points to the system is cruical
99+
>* Prototyping ideas
100+
>
101+
## Pros & Cons of using Monolithic Architecture
102+
>### Pros:
103+
>* Simple Development: Easy to develop and deploy.
104+
>* Unified Codebase: All code in one place, simplifying debugging.
105+
>* Better Performance: No inter-service communication overhead.
106+
>* Lower Costs: Minimal infrastructure and tooling requirements.
107+
>* Ease of Testing: Single application makes end-to-end testing straightforward.
108+
> * This is also assisted by the MVC structure employed in this example.
109+
>### Cons:
110+
>* Scalability Issues: Cannot scale individual components.
111+
>* Tight Coupling: Changes in one area may impact the whole system.
112+
>* Deployment Risks: A single failure can crash the entire application.
113+
>* Complex Maintenance: Harder to manage as the codebase grows.
114+
>* Limited Flexibility: Difficult to adopt new technologies for specific parts.
115+
116+
## Real-World Applications of Monolithic architecture Pattern in Java
117+
>* E-Commerce Platforms
118+
>* Content Management Systems (CMS)
119+
>* Banking and Financial Systems
120+
>* Enterprise Resource Planning (ERP) Systems
121+
>* Retail Point of Sale (POS) Systems
122+
123+
## References
124+
>* [GeeksforGeeks](https://www.geeksforgeeks.org/monolithic-architecture-system-design/)
125+
>* [Wikipedia](https://en.wikipedia.org/wiki/Monolithic_application)
126+
>* [vFunction](https://vfunction.com/blog/what-is-monolithic-application/#:~:text=A%20traditional%20e%2Dcommerce%20platform,inseparable%20components%20of%20the%20system.) Blog post
127+
>* [Microservices.io](https://microservices.io/patterns/monolithic.html)
128+
>* [IBM](https://www.ibm.com/think/topics/monolithic-architecture)
129+
>#### References used to create the code
130+
>* [Mockito](https://site.mockito.org/) -Testing
131+
>* [Junit](https://junit.org/junit5/docs/current/user-guide/) -Testing
132+
>* [Springboot](https://docs.spring.io/spring-boot/index.html) -Web Application Initiation (implemented but not utilized in this example)
133+
>* [Sprint Data Jpa](https://docs.spring.io/spring-data/jpa/reference/index.html) -Database connection
134+
>* [Lombok](https://projectlombok.org/) -Simplifying Classes
135+
>* [Log4j](https://logging.apache.org/log4j/2.x/index.html) -Capturing Logs
136+
>* [H2 Databse](https://www.h2database.com/html/tutorial.html) -Efficient, Simple, Dynamic Databse
Lines changed: 123 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,123 @@
1+
@startuml
2+
package com.iluwatar.monolithic.model {
3+
class Orders {
4+
- id : Long
5+
- product : Products
6+
- quantity : Integer
7+
- totalPrice : Double
8+
- user : User
9+
+ Orders()
10+
+ Orders(id : Long, user : User, product : Products, quantity : Integer, totalPrice : Double)
11+
# canEqual(other : Object) : boolean
12+
+ equals(o : Object) : boolean
13+
+ getId() : Long
14+
+ getProduct() : Products
15+
+ getQuantity() : Integer
16+
+ getTotalPrice() : Double
17+
+ getUser() : User
18+
+ hashCode() : int
19+
+ setId(id : Long)
20+
+ setProduct(product : Products)
21+
+ setQuantity(quantity : Integer)
22+
+ setTotalPrice(totalPrice : Double)
23+
+ setUser(user : User)
24+
+ toString() : String
25+
}
26+
class Products {
27+
- description : String
28+
- id : Long
29+
- name : String
30+
- price : Double
31+
- stock : Integer
32+
+ Products()
33+
+ Products(id : Long, name : String, description : String, price : Double, stock : Integer)
34+
# canEqual(other : Object) : boolean
35+
+ equals(o : Object) : boolean
36+
+ getDescription() : String
37+
+ getId() : Long
38+
+ getName() : String
39+
+ getPrice() : Double
40+
+ getStock() : Integer
41+
+ hashCode() : int
42+
+ setDescription(description : String)
43+
+ setId(id : Long)
44+
+ setName(name : String)
45+
+ setPrice(price : Double)
46+
+ setStock(stock : Integer)
47+
+ toString() : String
48+
}
49+
class User {
50+
- email : String
51+
- id : Long
52+
- name : String
53+
- password : String
54+
+ User()
55+
+ User(id : Long, name : String, email : String, password : String)
56+
# canEqual(other : Object) : boolean
57+
+ equals(o : Object) : boolean
58+
+ getEmail() : String
59+
+ getId() : Long
60+
+ getName() : String
61+
+ getPassword() : String
62+
+ hashCode() : int
63+
+ setEmail(email : String)
64+
+ setId(id : Long)
65+
+ setName(name : String)
66+
+ setPassword(password : String)
67+
+ toString() : String
68+
}
69+
}
70+
package com.iluwatar.monolithic.repository {
71+
interface OrderRepo {
72+
}
73+
interface ProductRepo {
74+
}
75+
interface UserRepo {
76+
+ findByEmail(String) : User {abstract}
77+
}
78+
}
79+
package com.iluwatar.monolithic.controller {
80+
class OrderCon {
81+
- orderRepository : OrderRepo
82+
- productRepository : ProductRepo
83+
- userRepository : UserRepo
84+
+ OrderCon(orderRepository : OrderRepo, userRepository : UserRepo, productRepository : ProductRepo)
85+
+ placeOrder(userId : Long, productId : Long, quantity : Integer) : Orders
86+
}
87+
class ProductCon {
88+
- productRepository : ProductRepo
89+
+ ProductCon(productRepository : ProductRepo)
90+
+ addProduct(product : Products) : Products
91+
+ getAllProducts() : List<Products>
92+
}
93+
class UserCon {
94+
- userRepository : UserRepo
95+
+ UserCon(userRepository : UserRepo)
96+
+ registerUser(user : User) : User
97+
}
98+
}
99+
package com.iluwatar.monolithic {
100+
class EcommerceApp {
101+
- log : Logger {static}
102+
- orderService : OrderCon
103+
- productService : ProductCon
104+
- userService : UserCon
105+
+ EcommerceApp(userService : UserCon, productService : ProductCon, orderService : OrderCon)
106+
# addProduct(scanner : Scanner)
107+
+ main(args : String[]) {static}
108+
# placeOrder(scanner : Scanner)
109+
# registerUser(scanner : Scanner)
110+
+ run(args : String[])
111+
}
112+
}
113+
UserCon --> "-userRepository" UserRepo
114+
Orders --> "-user" User
115+
OrderCon --> "-productRepository" ProductRepo
116+
OrderCon --> "-userRepository" UserRepo
117+
OrderCon --> "-orderRepository" OrderRepo
118+
EcommerceApp --> "-userService" UserCon
119+
Orders --> "-product" Products
120+
ProductCon --> "-productRepository" ProductRepo
121+
EcommerceApp --> "-productService" ProductCon
122+
EcommerceApp --> "-orderService" OrderCon
123+
@enduml

Monolithic-Ecommerce/pom.xml renamed to monolithic-architecture/pom.xml

Lines changed: 25 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
-->
2828
<project xmlns="http://maven.apache.org/POM/4.0.0"
2929
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
30-
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
30+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
3131
<modelVersion>4.0.0</modelVersion>
3232

3333
<parent>
@@ -36,8 +36,7 @@
3636
<version>1.26.0-SNAPSHOT</version>
3737
</parent>
3838

39-
<artifactId>Monolithic-Ecommerce</artifactId>
40-
39+
<artifactId>monolithic-architecture</artifactId>
4140

4241
<dependencies>
4342
<!-- Spring Boot Starter Web -->
@@ -80,6 +79,29 @@
8079
<scope>test</scope>
8180
</dependency>
8281
</dependencies>
82+
83+
<build>
84+
<plugins>
85+
<plugin>
86+
<groupId>org.apache.maven.plugins</groupId>
87+
<artifactId>maven-assembly-plugin</artifactId>
88+
<executions>
89+
<execution>
90+
<configuration>
91+
<archive>
92+
<manifest>
93+
<mainClass>com.iluwatar.monolithic.EcommerceApp</mainClass>
94+
</manifest>
95+
</archive>
96+
<descriptorRefs>
97+
<descriptorRef>jar-with-dependencies</descriptorRef>
98+
</descriptorRefs>
99+
</configuration>
100+
</execution>
101+
</executions>
102+
</plugin>
103+
</plugins>
104+
</build>
83105
</project>
84106

85107

Monolithic-Ecommerce/src/main/java/com/iluwatar/monolithic/EcommerceApp.java renamed to monolithic-architecture/src/main/java/com/iluwatar/monolithic/EcommerceApp.java

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,16 @@
3939

4040
/**
4141
* Main entry point for the Monolithic E-commerce application.
42+
* ------------------------------------------------------------------------
43+
* Monolithic architecture is a software design pattern where all components
44+
* of the application (presentation, business logic, and data access layers)
45+
* are part of a single unified codebase and deployable unit.
46+
* ------------------------------------------------------------------------
47+
* This example implements a monolithic architecture by integrating
48+
* user management, product management, and order placement within
49+
* the same application, sharing common resources and a single database.
4250
*/
51+
4352
@SpringBootApplication
4453
public class EcommerceApp implements CommandLineRunner {
4554

Monolithic-Ecommerce/src/main/java/com/iluwatar/monolithic/controller/OrderCon.java renamed to monolithic-architecture/src/main/java/com/iluwatar/monolithic/controller/OrderCon.java

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -53,24 +53,18 @@ public OrderCon(OrderRepo orderRepository, UserRepo userRepository, ProductRepo
5353
* This function handles placing orders with all of its cases.
5454
* */
5555
public Orders placeOrder(Long userId, Long productId, Integer quantity) {
56-
User user = userRepository.findById(userId).orElse(null);
57-
if (user == null) {
58-
throw new NonExistentUserException("User with ID " + userId + " not found");
59-
}
60-
61-
Products product = productRepository.findById(productId).orElse(null);
62-
if (product == null) {
63-
throw new NonExistentProductException("Product with ID " + productId + " not found");
64-
}
56+
final User user = userRepository.findById(userId).orElseThrow(() -> new NonExistentUserException("User with ID " + userId + " not found"));
6557

58+
final Products product = productRepository.findById(productId).orElseThrow(() -> new NonExistentProductException("Product with ID " + productId + " not found"));
59+
6660
if (product.getStock() < quantity) {
6761
throw new InsufficientStockException("Not enough stock for product " + productId);
6862
}
6963

7064
product.setStock(product.getStock() - quantity);
7165
productRepository.save(product);
7266

73-
Orders order = new Orders(null, user, product, quantity, product.getPrice() * quantity);
67+
final Orders order = new Orders(null, user, product, quantity, product.getPrice() * quantity);
7468
return orderRepository.save(order);
7569
}
7670
}

0 commit comments

Comments
 (0)