-
-
Notifications
You must be signed in to change notification settings - Fork 27.3k
Implemented Monolithic Architecture according to the guidelines provided by issue #2664 #3111
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 14 commits
Commits
Show all changes
19 commits
Select commit
Hold shift + click to select a range
18be6b4
added a pom.xml file for the monolithic structure, set up MVC file st…
916d683
added a pom.xml file for the monolithic structure, set up MVC file st…
d83632d
Added "controllers" and repository classes to communicate with databa…
1c6c98b
Merge remote-tracking branch 'origin/master'
2649ee8
added application.properties file for springboot, added controller cl…
31222a1
fixed checkstyle comments
e926e60
fixed testing class
b5b6c02
automatically generated puml
d5965a4
Readme File
dc2c6a5
attempting to fix some debugging issues
c56393f
dropped change
ef03a2c
another attempted fix
db565da
Merge branch 'Monolithic-Ecommerce'
784d45e
added more test cases
5b03784
Fixes
21b083f
Merge branch 'Monolithic-Ecommerce'
be82b9c
Merge branch 'master' into master
MohanedAtef238 798e8dc
fixed naming and readme file
dfbfc1e
Merge branch 'master' into master
iluwatar File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,126 @@ | ||
| ## 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. | ||
|
|
||
| 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. | ||
| > | ||
| ## 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 | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| 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 |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,85 @@ | ||
| <?xml version="1.0" encoding="UTF-8"?> | ||
| <!-- | ||
|
|
||
| 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. | ||
|
|
||
| --> | ||
| <project xmlns="http://maven.apache.org/POM/4.0.0" | ||
| xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
| xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
| <modelVersion>4.0.0</modelVersion> | ||
|
|
||
| <parent> | ||
| <groupId>com.iluwatar</groupId> | ||
| <artifactId>java-design-patterns</artifactId> | ||
| <version>1.26.0-SNAPSHOT</version> | ||
| </parent> | ||
|
|
||
| <artifactId>Monolithic-Ecommerce</artifactId> | ||
|
|
||
|
|
||
| <dependencies> | ||
| <!-- Spring Boot Starter Web --> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-web</artifactId> | ||
| </dependency> | ||
|
|
||
| <!-- Spring Boot Starter Data JPA --> | ||
| <dependency> | ||
| <groupId>org.springframework.boot</groupId> | ||
| <artifactId>spring-boot-starter-data-jpa</artifactId> | ||
| </dependency> | ||
|
|
||
| <!-- H2 Database --> | ||
| <dependency> | ||
| <groupId>com.h2database</groupId> | ||
| <artifactId>h2</artifactId> | ||
| <scope>runtime</scope> | ||
| </dependency> | ||
|
|
||
| <!-- Jakarta Persistence API --> | ||
| <dependency> | ||
| <groupId>jakarta.persistence</groupId> | ||
| <artifactId>jakarta.persistence-api</artifactId> | ||
| <version>3.1.0</version> | ||
| </dependency> | ||
|
|
||
| <!-- JUnit for Testing --> | ||
| <dependency> | ||
| <groupId>org.junit.jupiter</groupId> | ||
| <artifactId>junit-jupiter-engine</artifactId> | ||
| <scope>test</scope> | ||
| </dependency> | ||
|
|
||
| <!-- Mockito for Unit Testing --> | ||
| <dependency> | ||
| <groupId>org.mockito</groupId> | ||
| <artifactId>mockito-core</artifactId> | ||
| <scope>test</scope> | ||
| </dependency> | ||
| </dependencies> | ||
| </project> | ||
|
|
||
iluwatar marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.