|
import streamlit as st |
|
from utils.code_examples import monolithic_example |
|
from utils.quiz import monolithic_quiz |
|
|
|
st.title("Monolithic Architecture") |
|
|
|
st.write(""" |
|
Monolithic architecture is a traditional unified model for designing software programs. |
|
In this architecture, all components of the application are interconnected and interdependent, |
|
forming a single, indivisible unit. |
|
""") |
|
|
|
st.subheader("Characteristics of Monolithic Architecture") |
|
st.write(""" |
|
1. **Single Codebase**: The entire application is contained within a single codebase. |
|
2. **Shared Database**: All modules typically share a single database. |
|
3. **Tightly Coupled**: Components are interconnected and interdependent. |
|
4. **Single Deployment Unit**: The entire application is deployed as a single unit. |
|
""") |
|
|
|
st.subheader("Advantages and Disadvantages") |
|
col1, col2 = st.columns(2) |
|
|
|
with col1: |
|
st.markdown("**Advantages**") |
|
st.write(""" |
|
- Simple to develop |
|
- Easy to deploy |
|
- Good performance (no network latency between components) |
|
""") |
|
|
|
with col2: |
|
st.markdown("**Disadvantages**") |
|
st.write(""" |
|
- Can become complex as the application grows |
|
- Difficult to scale individual components |
|
- Technology stack is shared across the entire application |
|
- Changes can affect the entire system |
|
""") |
|
|
|
st.subheader("Example of a Monolithic Architecture") |
|
|
|
st.write("Here's a simplified example of a monolithic e-commerce application with a product recommendation system:") |
|
|
|
|
|
python_tab, java_tab = st.tabs(["Python", "Java"]) |
|
|
|
with python_tab: |
|
st.code(monolithic_example, language="python") |
|
|
|
with java_tab: |
|
java_monolithic_example = """ |
|
import java.util.*; |
|
|
|
class EcommerceApp { |
|
private Map<String, User> users = new HashMap<>(); |
|
private Map<Integer, Product> products = new HashMap<>(); |
|
private Map<Integer, Order> orders = new HashMap<>(); |
|
private Map<Integer, Payment> payments = new HashMap<>(); |
|
private Map<String, List<String>> userPreferences = new HashMap<>(); |
|
|
|
public void registerUser(String username, String password) { |
|
users.put(username, new User(username, password)); |
|
userPreferences.put(username, new ArrayList<>()); |
|
} |
|
|
|
public void addProduct(int productId, String name, double price, String category) { |
|
products.put(productId, new Product(productId, name, price, category)); |
|
} |
|
|
|
public Integer createOrder(String user, int productId, int quantity) { |
|
if (users.containsKey(user) && products.containsKey(productId)) { |
|
int orderId = orders.size() + 1; |
|
orders.put(orderId, new Order(orderId, user, productId, quantity)); |
|
userPreferences.get(user).add(products.get(productId).getCategory()); |
|
return orderId; |
|
} |
|
return null; |
|
} |
|
|
|
public boolean processPayment(int orderId, String paymentMethod) { |
|
if (orders.containsKey(orderId)) { |
|
payments.put(orderId, new Payment(paymentMethod, "completed")); |
|
return true; |
|
} |
|
return false; |
|
} |
|
|
|
public List<Product> recommendProducts(String user, int numRecommendations) { |
|
if (!userPreferences.containsKey(user) || userPreferences.get(user).isEmpty()) { |
|
return new ArrayList<>(products.values()).subList(0, Math.min(numRecommendations, products.size())); |
|
} |
|
|
|
List<String> userCategories = userPreferences.get(user); |
|
String mostCommonCategory = getMostCommonCategory(userCategories); |
|
|
|
List<Product> recommendedProducts = products.values().stream() |
|
.filter(p -> p.getCategory().equals(mostCommonCategory)) |
|
.limit(numRecommendations) |
|
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); |
|
|
|
if (recommendedProducts.size() < numRecommendations) { |
|
List<Product> otherProducts = products.values().stream() |
|
.filter(p -> !p.getCategory().equals(mostCommonCategory)) |
|
.limit(numRecommendations - recommendedProducts.size()) |
|
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll); |
|
recommendedProducts.addAll(otherProducts); |
|
} |
|
|
|
return recommendedProducts; |
|
} |
|
|
|
private String getMostCommonCategory(List<String> categories) { |
|
return categories.stream() |
|
.collect(java.util.stream.Collectors.groupingBy(c -> c, java.util.stream.Collectors.counting())) |
|
.entrySet().stream() |
|
.max(Map.Entry.comparingByValue()) |
|
.map(Map.Entry::getKey) |
|
.orElse(null); |
|
} |
|
} |
|
|
|
// Helper classes (User, Product, Order, Payment) are omitted for brevity |
|
""" |
|
st.code(java_monolithic_example, language="java") |
|
|
|
st.write(""" |
|
In this example, all the main functionalities of the e-commerce application |
|
(user management, product management, order processing, payment handling, and product recommendations) |
|
are contained within a single application. They share the same data structures and are |
|
tightly coupled. |
|
""") |
|
|
|
st.subheader("Interactive Exercise: Exploring the Monolithic Architecture") |
|
|
|
st.write("Let's modify the monolithic application to enhance the product recommendation system.") |
|
|
|
new_feature = st.text_area("Add a new method to the EcommerceApp class to implement a more advanced product recommendation system:", |
|
height=200) |
|
|
|
if new_feature: |
|
updated_code = monolithic_example.replace("def recommend_products(self, user, num_recommendations=3):", new_feature) |
|
st.code(updated_code, language="python") |
|
st.write(""" |
|
Now that you've enhanced the product recommendation system, consider the following: |
|
1. How does this new feature interact with the existing components of the application? |
|
2. What challenges might you face if you want to scale just the recommendation system? |
|
3. How would you handle updates or maintenance for this feature in a monolithic architecture? |
|
""") |
|
|
|
st.markdown("---") |
|
|
|
st.subheader("Quiz: Monolithic Architecture Concepts") |
|
monolithic_quiz() |
|
|