ozayezerceli
commited on
Commit
•
0b0d1e4
1
Parent(s):
a6ac51b
Upload 3 files
Browse files- pages/cohesion.py +168 -0
- pages/coupling.py +148 -0
- pages/monolithic.py +154 -0
pages/cohesion.py
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from utils.code_examples import cohesion_examples
|
3 |
+
from utils.quiz import cohesion_quiz
|
4 |
+
|
5 |
+
st.title("Cohesion in Software Architecture")
|
6 |
+
|
7 |
+
st.write("""
|
8 |
+
Cohesion refers to the degree to which the elements within a module belong together.
|
9 |
+
High cohesion is generally associated with good software design.
|
10 |
+
""")
|
11 |
+
|
12 |
+
st.subheader("Types of Cohesion")
|
13 |
+
st.write("""
|
14 |
+
1. **Functional Cohesion**: All elements of the module are related to the performance of a single function.
|
15 |
+
2. **Sequential Cohesion**: Elements of a module are involved in activities where output from one element serves as input to another.
|
16 |
+
3. **Communicational Cohesion**: Elements of a module operate on the same data.
|
17 |
+
4. **Procedural Cohesion**: Elements of a module are involved in different and possibly unrelated actions that must be performed in a specific order.
|
18 |
+
5. **Temporal Cohesion**: Elements are related by the fact that they are processed at a particular time in program execution.
|
19 |
+
6. **Logical Cohesion**: Elements perform similar operations, but these operations are unrelated.
|
20 |
+
7. **Coincidental Cohesion**: Elements have no meaningful relationship to one another.
|
21 |
+
""")
|
22 |
+
|
23 |
+
st.subheader("Examples of Cohesion")
|
24 |
+
|
25 |
+
for i, (title, description, python_code) in enumerate(cohesion_examples, 1):
|
26 |
+
st.markdown(f"### Example {i}: {title}")
|
27 |
+
st.write(description)
|
28 |
+
|
29 |
+
# Create tabs for Python and Java examples
|
30 |
+
python_tab, java_tab = st.tabs(["Python", "Java"])
|
31 |
+
|
32 |
+
with python_tab:
|
33 |
+
st.code(python_code, language="python")
|
34 |
+
|
35 |
+
with java_tab:
|
36 |
+
if title == "Functional Cohesion":
|
37 |
+
java_code = """
|
38 |
+
class UserAuthentication {
|
39 |
+
private String username;
|
40 |
+
private String password;
|
41 |
+
|
42 |
+
public UserAuthentication(String username, String password) {
|
43 |
+
this.username = username;
|
44 |
+
this.password = password;
|
45 |
+
}
|
46 |
+
|
47 |
+
public String hashPassword() {
|
48 |
+
// Hash the password
|
49 |
+
return "hashed_" + password;
|
50 |
+
}
|
51 |
+
|
52 |
+
public boolean checkPasswordStrength() {
|
53 |
+
// Check if the password meets security requirements
|
54 |
+
return password.length() >= 8;
|
55 |
+
}
|
56 |
+
|
57 |
+
public boolean authenticate() {
|
58 |
+
// Authenticate the user
|
59 |
+
return username != null && password != null;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
"""
|
63 |
+
elif title == "Sequential Cohesion":
|
64 |
+
java_code = """
|
65 |
+
class OrderProcessor {
|
66 |
+
public Order processOrder(Order order) {
|
67 |
+
Order validatedOrder = validateOrder(order);
|
68 |
+
Order calculatedOrder = calculateTotal(validatedOrder);
|
69 |
+
return submitOrder(calculatedOrder);
|
70 |
+
}
|
71 |
+
|
72 |
+
private Order validateOrder(Order order) {
|
73 |
+
// Validate the order
|
74 |
+
order.setValid(true);
|
75 |
+
return order;
|
76 |
+
}
|
77 |
+
|
78 |
+
private Order calculateTotal(Order order) {
|
79 |
+
// Calculate the total price
|
80 |
+
order.setTotal(100.0); // Dummy calculation
|
81 |
+
return order;
|
82 |
+
}
|
83 |
+
|
84 |
+
private Order submitOrder(Order order) {
|
85 |
+
// Submit the order to the system
|
86 |
+
order.setSubmitted(true);
|
87 |
+
return order;
|
88 |
+
}
|
89 |
+
}
|
90 |
+
"""
|
91 |
+
elif title == "Communicational Cohesion":
|
92 |
+
java_code = """
|
93 |
+
class UserManager {
|
94 |
+
private User userData;
|
95 |
+
|
96 |
+
public UserManager(User userData) {
|
97 |
+
this.userData = userData;
|
98 |
+
}
|
99 |
+
|
100 |
+
public boolean validateUser() {
|
101 |
+
// Validate user data
|
102 |
+
return userData.getName() != null && userData.getEmail() != null;
|
103 |
+
}
|
104 |
+
|
105 |
+
public void saveUser() {
|
106 |
+
// Save user to database
|
107 |
+
System.out.println("User saved: " + userData.getName());
|
108 |
+
}
|
109 |
+
|
110 |
+
public void sendWelcomeEmail() {
|
111 |
+
// Send welcome email to user
|
112 |
+
System.out.println("Welcome email sent to: " + userData.getEmail());
|
113 |
+
}
|
114 |
+
}
|
115 |
+
"""
|
116 |
+
st.code(java_code, language="java")
|
117 |
+
|
118 |
+
st.subheader("Interactive Exercise: Identify Cohesion Types")
|
119 |
+
st.write("Analyze the following code snippets and identify the type of cohesion present.")
|
120 |
+
|
121 |
+
code1 = """
|
122 |
+
class UserManager:
|
123 |
+
def create_user(self, username, email):
|
124 |
+
# logic to create user
|
125 |
+
pass
|
126 |
+
|
127 |
+
def delete_user(self, user_id):
|
128 |
+
# logic to delete user
|
129 |
+
pass
|
130 |
+
|
131 |
+
def update_user(self, user_id, new_data):
|
132 |
+
# logic to update user
|
133 |
+
pass
|
134 |
+
"""
|
135 |
+
|
136 |
+
code2 = """
|
137 |
+
class ReportGenerator:
|
138 |
+
def generate_sales_report(self):
|
139 |
+
# logic for sales report
|
140 |
+
pass
|
141 |
+
|
142 |
+
def generate_inventory_report(self):
|
143 |
+
# logic for inventory report
|
144 |
+
pass
|
145 |
+
|
146 |
+
def send_email(self, report):
|
147 |
+
# logic to send email
|
148 |
+
pass
|
149 |
+
"""
|
150 |
+
|
151 |
+
st.code(code1, language="python")
|
152 |
+
user_answer1 = st.selectbox("What type of cohesion is present in the first example?",
|
153 |
+
("Functional", "Sequential", "Communicational", "Procedural", "Temporal", "Logical", "Coincidental"))
|
154 |
+
|
155 |
+
st.code(code2, language="python")
|
156 |
+
user_answer2 = st.selectbox("What type of cohesion is present in the second example?",
|
157 |
+
("Functional", "Sequential", "Communicational", "Procedural", "Temporal", "Logical", "Coincidental"))
|
158 |
+
|
159 |
+
if st.button("Check Answers"):
|
160 |
+
if user_answer1 == "Functional" and user_answer2 == "Logical":
|
161 |
+
st.success("Correct! The UserManager class shows functional cohesion, while the ReportGenerator class shows logical cohesion.")
|
162 |
+
else:
|
163 |
+
st.error("Not quite. Try again!")
|
164 |
+
|
165 |
+
st.markdown("---")
|
166 |
+
|
167 |
+
st.subheader("Quiz: Cohesion Concepts")
|
168 |
+
cohesion_quiz()
|
pages/coupling.py
ADDED
@@ -0,0 +1,148 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from utils.code_examples import coupling_examples
|
3 |
+
|
4 |
+
st.title("Coupling in Software Architecture")
|
5 |
+
|
6 |
+
st.write("""
|
7 |
+
Coupling refers to the degree of interdependence between software modules.
|
8 |
+
Low coupling is typically a sign of a well-structured computer system and a good design.
|
9 |
+
""")
|
10 |
+
|
11 |
+
st.subheader("Types of Coupling")
|
12 |
+
st.write("""
|
13 |
+
1. **Tight Coupling**: Modules are highly dependent on each other.
|
14 |
+
2. **Loose Coupling**: Modules are relatively independent of each other.
|
15 |
+
""")
|
16 |
+
|
17 |
+
st.subheader("Examples of Coupling")
|
18 |
+
|
19 |
+
for i, (title, description, python_code) in enumerate(coupling_examples, 1):
|
20 |
+
st.markdown(f"### Example {i}: {title}")
|
21 |
+
st.write(description)
|
22 |
+
|
23 |
+
# Create tabs for Python and Java examples
|
24 |
+
python_tab, java_tab = st.tabs(["Python", "Java"])
|
25 |
+
|
26 |
+
with python_tab:
|
27 |
+
st.code(python_code, language="python")
|
28 |
+
|
29 |
+
with java_tab:
|
30 |
+
if title == "Tight Coupling":
|
31 |
+
java_code = """
|
32 |
+
class Database {
|
33 |
+
public User getUser(int userId) {
|
34 |
+
// database logic here
|
35 |
+
return new User(userId);
|
36 |
+
}
|
37 |
+
}
|
38 |
+
|
39 |
+
class UserService {
|
40 |
+
private Database db;
|
41 |
+
|
42 |
+
public UserService() {
|
43 |
+
this.db = new Database();
|
44 |
+
}
|
45 |
+
|
46 |
+
public User getUserInfo(int userId) {
|
47 |
+
return db.getUser(userId);
|
48 |
+
}
|
49 |
+
}
|
50 |
+
"""
|
51 |
+
elif title == "Loose Coupling":
|
52 |
+
java_code = """
|
53 |
+
class Database {
|
54 |
+
public User getUser(int userId) {
|
55 |
+
// database logic here
|
56 |
+
return new User(userId);
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
class UserService {
|
61 |
+
private Database db;
|
62 |
+
|
63 |
+
public UserService(Database database) {
|
64 |
+
this.db = database;
|
65 |
+
}
|
66 |
+
|
67 |
+
public User getUserInfo(int userId) {
|
68 |
+
return db.getUser(userId);
|
69 |
+
}
|
70 |
+
}
|
71 |
+
"""
|
72 |
+
elif title == "Decoupling with Interfaces":
|
73 |
+
java_code = """
|
74 |
+
interface DatabaseInterface {
|
75 |
+
User getUser(int userId);
|
76 |
+
}
|
77 |
+
|
78 |
+
class DatabaseImpl implements DatabaseInterface {
|
79 |
+
public User getUser(int userId) {
|
80 |
+
// database logic here
|
81 |
+
return new User(userId);
|
82 |
+
}
|
83 |
+
}
|
84 |
+
|
85 |
+
class UserService {
|
86 |
+
private DatabaseInterface db;
|
87 |
+
|
88 |
+
public UserService(DatabaseInterface database) {
|
89 |
+
this.db = database;
|
90 |
+
}
|
91 |
+
|
92 |
+
public User getUserInfo(int userId) {
|
93 |
+
return db.getUser(userId);
|
94 |
+
}
|
95 |
+
}
|
96 |
+
"""
|
97 |
+
st.code(java_code, language="java")
|
98 |
+
|
99 |
+
st.subheader("Interactive Exercise: Identify Coupling Issues")
|
100 |
+
st.write("Analyze the following code snippets and identify the type of coupling present.")
|
101 |
+
|
102 |
+
code1 = """
|
103 |
+
class Database:
|
104 |
+
def get_user(self, user_id):
|
105 |
+
# database logic here
|
106 |
+
pass
|
107 |
+
|
108 |
+
class UserService:
|
109 |
+
def __init__(self):
|
110 |
+
self.db = Database()
|
111 |
+
|
112 |
+
def get_user_info(self, user_id):
|
113 |
+
return self.db.get_user(user_id)
|
114 |
+
"""
|
115 |
+
|
116 |
+
code2 = """
|
117 |
+
class Database:
|
118 |
+
def get_user(self, user_id):
|
119 |
+
# database logic here
|
120 |
+
pass
|
121 |
+
|
122 |
+
class UserService:
|
123 |
+
def __init__(self, database):
|
124 |
+
self.db = database
|
125 |
+
|
126 |
+
def get_user_info(self, user_id):
|
127 |
+
return self.db.get_user(user_id)
|
128 |
+
"""
|
129 |
+
|
130 |
+
st.code(code1, language="python")
|
131 |
+
user_answer1 = st.radio("What type of coupling is present in the first example?",
|
132 |
+
("Tight Coupling", "Loose Coupling"))
|
133 |
+
|
134 |
+
st.code(code2, language="python")
|
135 |
+
user_answer2 = st.radio("What type of coupling is present in the second example?",
|
136 |
+
("Tight Coupling", "Loose Coupling"))
|
137 |
+
|
138 |
+
if st.button("Check Answers"):
|
139 |
+
if user_answer1 == "Tight Coupling" and user_answer2 == "Loose Coupling":
|
140 |
+
st.success("Correct! The first example shows tight coupling, while the second shows loose coupling.")
|
141 |
+
else:
|
142 |
+
st.error("Not quite. Try again!")
|
143 |
+
|
144 |
+
st.markdown("---")
|
145 |
+
|
146 |
+
st.subheader("Quiz: Coupling Concepts")
|
147 |
+
from utils.quiz import coupling_quiz
|
148 |
+
coupling_quiz()
|
pages/monolithic.py
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import streamlit as st
|
2 |
+
from utils.code_examples import monolithic_example
|
3 |
+
from utils.quiz import monolithic_quiz
|
4 |
+
|
5 |
+
st.title("Monolithic Architecture")
|
6 |
+
|
7 |
+
st.write("""
|
8 |
+
Monolithic architecture is a traditional unified model for designing software programs.
|
9 |
+
In this architecture, all components of the application are interconnected and interdependent,
|
10 |
+
forming a single, indivisible unit.
|
11 |
+
""")
|
12 |
+
|
13 |
+
st.subheader("Characteristics of Monolithic Architecture")
|
14 |
+
st.write("""
|
15 |
+
1. **Single Codebase**: The entire application is contained within a single codebase.
|
16 |
+
2. **Shared Database**: All modules typically share a single database.
|
17 |
+
3. **Tightly Coupled**: Components are interconnected and interdependent.
|
18 |
+
4. **Single Deployment Unit**: The entire application is deployed as a single unit.
|
19 |
+
""")
|
20 |
+
|
21 |
+
st.subheader("Advantages and Disadvantages")
|
22 |
+
col1, col2 = st.columns(2)
|
23 |
+
|
24 |
+
with col1:
|
25 |
+
st.markdown("**Advantages**")
|
26 |
+
st.write("""
|
27 |
+
- Simple to develop
|
28 |
+
- Easy to deploy
|
29 |
+
- Good performance (no network latency between components)
|
30 |
+
""")
|
31 |
+
|
32 |
+
with col2:
|
33 |
+
st.markdown("**Disadvantages**")
|
34 |
+
st.write("""
|
35 |
+
- Can become complex as the application grows
|
36 |
+
- Difficult to scale individual components
|
37 |
+
- Technology stack is shared across the entire application
|
38 |
+
- Changes can affect the entire system
|
39 |
+
""")
|
40 |
+
|
41 |
+
st.subheader("Example of a Monolithic Architecture")
|
42 |
+
|
43 |
+
st.write("Here's a simplified example of a monolithic e-commerce application with a product recommendation system:")
|
44 |
+
|
45 |
+
# Create tabs for Python and Java examples
|
46 |
+
python_tab, java_tab = st.tabs(["Python", "Java"])
|
47 |
+
|
48 |
+
with python_tab:
|
49 |
+
st.code(monolithic_example, language="python")
|
50 |
+
|
51 |
+
with java_tab:
|
52 |
+
java_monolithic_example = """
|
53 |
+
import java.util.*;
|
54 |
+
|
55 |
+
class EcommerceApp {
|
56 |
+
private Map<String, User> users = new HashMap<>();
|
57 |
+
private Map<Integer, Product> products = new HashMap<>();
|
58 |
+
private Map<Integer, Order> orders = new HashMap<>();
|
59 |
+
private Map<Integer, Payment> payments = new HashMap<>();
|
60 |
+
private Map<String, List<String>> userPreferences = new HashMap<>();
|
61 |
+
|
62 |
+
public void registerUser(String username, String password) {
|
63 |
+
users.put(username, new User(username, password));
|
64 |
+
userPreferences.put(username, new ArrayList<>());
|
65 |
+
}
|
66 |
+
|
67 |
+
public void addProduct(int productId, String name, double price, String category) {
|
68 |
+
products.put(productId, new Product(productId, name, price, category));
|
69 |
+
}
|
70 |
+
|
71 |
+
public Integer createOrder(String user, int productId, int quantity) {
|
72 |
+
if (users.containsKey(user) && products.containsKey(productId)) {
|
73 |
+
int orderId = orders.size() + 1;
|
74 |
+
orders.put(orderId, new Order(orderId, user, productId, quantity));
|
75 |
+
userPreferences.get(user).add(products.get(productId).getCategory());
|
76 |
+
return orderId;
|
77 |
+
}
|
78 |
+
return null;
|
79 |
+
}
|
80 |
+
|
81 |
+
public boolean processPayment(int orderId, String paymentMethod) {
|
82 |
+
if (orders.containsKey(orderId)) {
|
83 |
+
payments.put(orderId, new Payment(paymentMethod, "completed"));
|
84 |
+
return true;
|
85 |
+
}
|
86 |
+
return false;
|
87 |
+
}
|
88 |
+
|
89 |
+
public List<Product> recommendProducts(String user, int numRecommendations) {
|
90 |
+
if (!userPreferences.containsKey(user) || userPreferences.get(user).isEmpty()) {
|
91 |
+
return new ArrayList<>(products.values()).subList(0, Math.min(numRecommendations, products.size()));
|
92 |
+
}
|
93 |
+
|
94 |
+
List<String> userCategories = userPreferences.get(user);
|
95 |
+
String mostCommonCategory = getMostCommonCategory(userCategories);
|
96 |
+
|
97 |
+
List<Product> recommendedProducts = products.values().stream()
|
98 |
+
.filter(p -> p.getCategory().equals(mostCommonCategory))
|
99 |
+
.limit(numRecommendations)
|
100 |
+
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
101 |
+
|
102 |
+
if (recommendedProducts.size() < numRecommendations) {
|
103 |
+
List<Product> otherProducts = products.values().stream()
|
104 |
+
.filter(p -> !p.getCategory().equals(mostCommonCategory))
|
105 |
+
.limit(numRecommendations - recommendedProducts.size())
|
106 |
+
.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
|
107 |
+
recommendedProducts.addAll(otherProducts);
|
108 |
+
}
|
109 |
+
|
110 |
+
return recommendedProducts;
|
111 |
+
}
|
112 |
+
|
113 |
+
private String getMostCommonCategory(List<String> categories) {
|
114 |
+
return categories.stream()
|
115 |
+
.collect(java.util.stream.Collectors.groupingBy(c -> c, java.util.stream.Collectors.counting()))
|
116 |
+
.entrySet().stream()
|
117 |
+
.max(Map.Entry.comparingByValue())
|
118 |
+
.map(Map.Entry::getKey)
|
119 |
+
.orElse(null);
|
120 |
+
}
|
121 |
+
}
|
122 |
+
|
123 |
+
// Helper classes (User, Product, Order, Payment) are omitted for brevity
|
124 |
+
"""
|
125 |
+
st.code(java_monolithic_example, language="java")
|
126 |
+
|
127 |
+
st.write("""
|
128 |
+
In this example, all the main functionalities of the e-commerce application
|
129 |
+
(user management, product management, order processing, payment handling, and product recommendations)
|
130 |
+
are contained within a single application. They share the same data structures and are
|
131 |
+
tightly coupled.
|
132 |
+
""")
|
133 |
+
|
134 |
+
st.subheader("Interactive Exercise: Exploring the Monolithic Architecture")
|
135 |
+
|
136 |
+
st.write("Let's modify the monolithic application to enhance the product recommendation system.")
|
137 |
+
|
138 |
+
new_feature = st.text_area("Add a new method to the EcommerceApp class to implement a more advanced product recommendation system:",
|
139 |
+
height=200)
|
140 |
+
|
141 |
+
if new_feature:
|
142 |
+
updated_code = monolithic_example.replace("def recommend_products(self, user, num_recommendations=3):", new_feature)
|
143 |
+
st.code(updated_code, language="python")
|
144 |
+
st.write("""
|
145 |
+
Now that you've enhanced the product recommendation system, consider the following:
|
146 |
+
1. How does this new feature interact with the existing components of the application?
|
147 |
+
2. What challenges might you face if you want to scale just the recommendation system?
|
148 |
+
3. How would you handle updates or maintenance for this feature in a monolithic architecture?
|
149 |
+
""")
|
150 |
+
|
151 |
+
st.markdown("---")
|
152 |
+
|
153 |
+
st.subheader("Quiz: Monolithic Architecture Concepts")
|
154 |
+
monolithic_quiz()
|