Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
sugan0tech authored Feb 19, 2025
2 parents a53c5d9 + e17f138 commit 0dc87ed
Show file tree
Hide file tree
Showing 28 changed files with 1,529 additions and 13 deletions.
18 changes: 18 additions & 0 deletions .all-contributorsrc
Original file line number Diff line number Diff line change
Expand Up @@ -3393,6 +3393,24 @@
"contributions": [
"code"
]
},
{
"login": "MohanedAtef238",
"name": "Mohaned Atef",
"avatar_url": "https://avatars.githubusercontent.com/u/105852138?v=4",
"profile": "https://github.com/MohanedAtef238",
"contributions": [
"code"
]
},
{
"login": "maximevtush",
"name": "Maxim Evtush",
"avatar_url": "https://avatars.githubusercontent.com/u/154841002?v=4",
"profile": "https://github.com/maximevtush",
"contributions": [
"code"
]
}
],
"contributorsPerLine": 6,
Expand Down
6 changes: 5 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
[![Coverage](https://sonarcloud.io/api/project_badges/measure?project=iluwatar_java-design-patterns&metric=coverage)](https://sonarcloud.io/dashboard?id=iluwatar_java-design-patterns)
[![Join the chat at https://gitter.im/iluwatar/java-design-patterns](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/iluwatar/java-design-patterns?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
<!-- ALL-CONTRIBUTORS-BADGE:START - Do not remove or modify this section -->
[![All Contributors](https://img.shields.io/badge/all_contributors-372-orange.svg?style=flat-square)](#contributors-)
[![All Contributors](https://img.shields.io/badge/all_contributors-374-orange.svg?style=flat-square)](#contributors-)
<!-- ALL-CONTRIBUTORS-BADGE:END -->

<br/>
Expand Down Expand Up @@ -556,6 +556,10 @@ This project is licensed under the terms of the MIT license.
<td align="center" valign="top" width="16.66%"><a href="https://github.com/clintaire"><img src="https://avatars.githubusercontent.com/u/111376518?v=4?s=100" width="100px;" alt="Clint Airé"/><br /><sub><b>Clint Airé</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=clintaire" title="Code">💻</a></td>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/darkhyper24"><img src="https://avatars.githubusercontent.com/u/132711528?v=4?s=100" width="100px;" alt="darkhyper24"/><br /><sub><b>darkhyper24</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=darkhyper24" title="Code">💻</a></td>
</tr>
<tr>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/MohanedAtef238"><img src="https://avatars.githubusercontent.com/u/105852138?v=4?s=100" width="100px;" alt="Mohaned Atef"/><br /><sub><b>Mohaned Atef</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=MohanedAtef238" title="Code">💻</a></td>
<td align="center" valign="top" width="16.66%"><a href="https://github.com/maximevtush"><img src="https://avatars.githubusercontent.com/u/154841002?v=4?s=100" width="100px;" alt="Maxim Evtush"/><br /><sub><b>Maxim Evtush</b></sub></a><br /><a href="https://github.com/iluwatar/java-design-patterns/commits?author=maximevtush" title="Code">💻</a></td>
</tr>
</tbody>
</table>

Expand Down
2 changes: 1 addition & 1 deletion bloc/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@
<dependency>
<groupId>org.testng</groupId>
<artifactId>testng</artifactId>
<version>7.7.1</version>
<version>7.11.0</version>
<scope>test</scope>
</dependency>
<dependency>
Expand Down
4 changes: 2 additions & 2 deletions caching/etc/caching.urm.puml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ package com.iluwatar.caching {
- LOGGER : Logger {static}
+ App()
+ main(args : String[]) {static}
+ useCacheAsideStategy()
+ useCacheAsideStrategy()
+ useReadAndWriteThroughStrategy()
+ useReadThroughAndWriteAroundStrategy()
+ useReadThroughAndWriteBehindStrategy()
Expand Down Expand Up @@ -116,4 +116,4 @@ Node --> "-previous" Node
AppManager --> "-cachingPolicy" CachingPolicy
Node --> "-userAccount" UserAccount
CacheStore --> "-cache" LruCache
@enduml
@enduml
4 changes: 2 additions & 2 deletions caching/src/main/java/com/iluwatar/caching/App.java
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ public static void main(final String[] args) {
LOGGER.info(splitLine);
app.useReadThroughAndWriteBehindStrategy();
LOGGER.info(splitLine);
app.useCacheAsideStategy();
app.useCacheAsideStrategy();
LOGGER.info(splitLine);
}

Expand Down Expand Up @@ -224,7 +224,7 @@ public void useReadThroughAndWriteBehindStrategy() {
/**
* Cache-Aside.
*/
public void useCacheAsideStategy() {
public void useCacheAsideStrategy() {
LOGGER.info("# CachingPolicy.ASIDE");
appManager.initCachingPolicy(CachingPolicy.ASIDE);
LOGGER.info(appManager.printCacheContent());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,6 @@ void testReadThroughAndWriteBehindStrategy() {
@Test
void testCacheAsideStrategy() {
assertNotNull(app);
app.useCacheAsideStategy();
app.useCacheAsideStrategy();
}
}
4 changes: 2 additions & 2 deletions money/src/main/java/com/iluwatar/CannotSubtractException.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package com.iluwatar;
/**
* An exception for when the user tries to subtract two diffrent currencies or subtract an amount he doesn't have.
* An exception for when the user tries to subtract two different currencies or subtract an amount he doesn't have.
*/
public class CannotSubtractException extends Exception {
/**
Expand All @@ -12,4 +12,4 @@ public CannotSubtractException(String message) {
super(message);
}

}
}
150 changes: 150 additions & 0 deletions monolithic-architecture/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,150 @@
---
title: "Monolithic Ecommerce App: A Cohesive Application Model"
shortTitle: Monolithic Ecommerce
description: "Explore the Monolithic Ecommerce application structure, its design intent, benefits, limitations, and real-world applications. Understand its simplicity and practical use cases."
category: Architectural
language: en
tag:
- Cohesion
- Simplicity
- Scalability
- Deployment
- Maintainability
---

## Monolithic-Ecommerce App
* A Monolithic Ecommerce example to showcase Monolithic Architecture

## The Intent of Monolithic Design pattern
> 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.
## Detailed Explanation of the Monolithic Architecture
Real-world Example
> 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.
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.
GeeksforGeeks states
> 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.
Why use MVC for a Monolithic Application ?
>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:
>* Model
>* View
>* Controller
>
> this also helps maintain the principles of a Monolithic Architecture which are:
>
> Simple to
>* Develop
>* Test
>* Deploy
>* Scale
>
## We can clearly see that this is a Monolithic application through the main class
This is a simplified version of the main application that shows the main interaction point with the CLI and how a user is registered
```java
@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!");
}

}
```
### 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.

## When should you resort to a Monolithic Architecture ?
>* An enterprise Starting off with a relatively small team
>* Simplicity is the most important factor of the project
>* Maintaining less entry points to the system is cruical
>* Prototyping ideas
>
## Pros & Cons of using Monolithic Architecture
>### Pros:
>* Simple Development: Easy to develop and deploy.
>* Unified Codebase: All code in one place, simplifying debugging.
>* Better Performance: No inter-service communication overhead.
>* Lower Costs: Minimal infrastructure and tooling requirements.
>* Ease of Testing: Single application makes end-to-end testing straightforward.
> * This is also assisted by the MVC structure employed in this example.
>### Cons:
>* Scalability Issues: Cannot scale individual components.
>* Tight Coupling: Changes in one area may impact the whole system.
>* Deployment Risks: A single failure can crash the entire application.
>* Complex Maintenance: Harder to manage as the codebase grows.
>* Limited Flexibility: Difficult to adopt new technologies for specific parts.
## Real-World Applications of Monolithic architecture Pattern in Java
>* E-Commerce Platforms
>* Content Management Systems (CMS)
>* Banking and Financial Systems
>* Enterprise Resource Planning (ERP) Systems
>* Retail Point of Sale (POS) Systems
## References
>* [GeeksforGeeks](https://www.geeksforgeeks.org/monolithic-architecture-system-design/)
>* [Wikipedia](https://en.wikipedia.org/wiki/Monolithic_application)
>* [vFunction](https://vfunction.com/blog/what-is-monolithic-application/#:~:text=A%20traditional%20e%2Dcommerce%20platform,inseparable%20components%20of%20the%20system.) Blog post
>* [Microservices.io](https://microservices.io/patterns/monolithic.html)
>* [IBM](https://www.ibm.com/think/topics/monolithic-architecture)
>#### References used to create the code
>* [Mockito](https://site.mockito.org/) -Testing
>* [Junit](https://junit.org/junit5/docs/current/user-guide/) -Testing
>* [Springboot](https://docs.spring.io/spring-boot/index.html) -Web Application Initiation (implemented but not utilized in this example)
>* [Sprint Data Jpa](https://docs.spring.io/spring-data/jpa/reference/index.html) -Database connection
>* [Lombok](https://projectlombok.org/) -Simplifying Classes
>* [Log4j](https://logging.apache.org/log4j/2.x/index.html) -Capturing Logs
>* [H2 Databse](https://www.h2database.com/html/tutorial.html) -Efficient, Simple, Dynamic Databse
123 changes: 123 additions & 0 deletions monolithic-architecture/etc/Monolithic-Ecommerce.urm.puml
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
@startuml
package com.iluwatar.monolithic.model {
class Orders {
- id : Long
- product : Products
- quantity : Integer
- totalPrice : Double
- user : User
+ Orders()
+ Orders(id : Long, user : User, product : Products, quantity : Integer, totalPrice : Double)
# canEqual(other : Object) : boolean
+ equals(o : Object) : boolean
+ getId() : Long
+ getProduct() : Products
+ getQuantity() : Integer
+ getTotalPrice() : Double
+ getUser() : User
+ hashCode() : int
+ setId(id : Long)
+ setProduct(product : Products)
+ setQuantity(quantity : Integer)
+ setTotalPrice(totalPrice : Double)
+ setUser(user : User)
+ toString() : String
}
class Products {
- description : String
- id : Long
- name : String
- price : Double
- stock : Integer
+ Products()
+ Products(id : Long, name : String, description : String, price : Double, stock : Integer)
# canEqual(other : Object) : boolean
+ equals(o : Object) : boolean
+ getDescription() : String
+ getId() : Long
+ getName() : String
+ getPrice() : Double
+ getStock() : Integer
+ hashCode() : int
+ setDescription(description : String)
+ setId(id : Long)
+ setName(name : String)
+ setPrice(price : Double)
+ setStock(stock : Integer)
+ toString() : String
}
class User {
- email : String
- id : Long
- name : String
- password : String
+ User()
+ User(id : Long, name : String, email : String, password : String)
# canEqual(other : Object) : boolean
+ equals(o : Object) : boolean
+ getEmail() : String
+ getId() : Long
+ getName() : String
+ getPassword() : String
+ hashCode() : int
+ setEmail(email : String)
+ setId(id : Long)
+ setName(name : String)
+ setPassword(password : String)
+ toString() : String
}
}
package com.iluwatar.monolithic.repository {
interface OrderRepo {
}
interface ProductRepo {
}
interface UserRepo {
+ findByEmail(String) : User {abstract}
}
}
package com.iluwatar.monolithic.controller {
class OrderCon {
- orderRepository : OrderRepo
- productRepository : ProductRepo
- userRepository : UserRepo
+ OrderCon(orderRepository : OrderRepo, userRepository : UserRepo, productRepository : ProductRepo)
+ placeOrder(userId : Long, productId : Long, quantity : Integer) : Orders
}
class ProductCon {
- productRepository : ProductRepo
+ ProductCon(productRepository : ProductRepo)
+ addProduct(product : Products) : Products
+ getAllProducts() : List<Products>
}
class UserCon {
- userRepository : UserRepo
+ UserCon(userRepository : UserRepo)
+ registerUser(user : User) : User
}
}
package com.iluwatar.monolithic {
class EcommerceApp {
- log : Logger {static}
- orderService : OrderCon
- productService : ProductCon
- userService : UserCon
+ EcommerceApp(userService : UserCon, productService : ProductCon, orderService : OrderCon)
# addProduct(scanner : Scanner)
+ main(args : String[]) {static}
# placeOrder(scanner : Scanner)
# registerUser(scanner : Scanner)
+ run(args : String[])
}
}
UserCon --> "-userRepository" UserRepo
Orders --> "-user" User
OrderCon --> "-productRepository" ProductRepo
OrderCon --> "-userRepository" UserRepo
OrderCon --> "-orderRepository" OrderRepo
EcommerceApp --> "-userService" UserCon
EcommerceApp --> "-productService" ProductCon
ProductCon --> "-productRepository" ProductRepo
Orders --> "-product" Products
EcommerceApp --> "-orderService" OrderCon
@enduml
Loading

0 comments on commit 0dc87ed

Please sign in to comment.