Skip to content

Commit 252f706

Browse files
authored
Merge pull request #8400 from raynerpv2022/main
#32 - Python
2 parents 2d5a87b + aabe17e commit 252f706

File tree

3 files changed

+1625
-0
lines changed

3 files changed

+1625
-0
lines changed
Lines changed: 327 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,327 @@
1+
from abc import ABC, abstractmethod
2+
3+
# Ejercicio: Sistema de pedidos online con notificaciones
4+
5+
# Crea una aplicación sencilla que haga lo siguiente:
6+
# Se pueden crear distintos tipos de pedidos (por ejemplo, Electrónica, Ropa, Libros).
7+
# El pedido puede ser procesado.
8+
# El sistema puede notificar al cliente por distintos medios: Email, SMS o WhatsApp.
9+
# Los mensajes deben cumplir con Open/Closed y Dependency Inversion.
10+
# Añade una clase que simule una base de datos en memoria para almacenar los pedidos.
11+
12+
# classe virtual para ordenes
13+
class VirtualOrder(ABC):
14+
@abstractmethod
15+
def Process(self):
16+
pass
17+
18+
19+
# classes concretas para ordenes
20+
21+
class Internet(VirtualOrder):
22+
def __init__(self, name: str):
23+
self.name = name
24+
25+
def Process(self):
26+
return f"Internet Order {self.name} Processed"
27+
28+
class Electronic(VirtualOrder):
29+
def __init__(self, name: str):
30+
self.name = name
31+
32+
def Process(self):
33+
return f"Electronic Order {self.name} Processed"
34+
35+
class Clothes( VirtualOrder):
36+
def __init__(self, name: str):
37+
self.name = name
38+
39+
def Process(self):
40+
return f"Clothes Order {self.name} Processed"
41+
42+
class Books (VirtualOrder):
43+
def __init__(self, name: str):
44+
self.name = name
45+
46+
def Process(self):
47+
return f"Book Order {self.name} Processed"
48+
49+
50+
# classes virtual para notificaciones
51+
class VirtualNotification(ABC):
52+
@abstractmethod
53+
def SendNotification(self):
54+
pass
55+
56+
# classes concretas para notificaciones
57+
58+
class Telegram(VirtualNotification):
59+
def SendNotification(self):
60+
return " Telegram message sent"
61+
62+
class Email(VirtualNotification):
63+
def SendNotification(self):
64+
return " Email message sent"
65+
66+
class Sms (VirtualNotification):
67+
def SendNotification(self):
68+
return " SMS message sent"
69+
70+
class Whatsapp(VirtualNotification):
71+
def SendNotification(self):
72+
return " Whatsapp message sent"
73+
74+
75+
# classe virtual para repositorio
76+
class VirtualDataBaseinMemory(ABC):
77+
@abstractmethod
78+
def AddOrder(self,order: VirtualOrder):
79+
pass
80+
81+
@abstractmethod
82+
def ListOrder(self):
83+
pass
84+
85+
# classe concreta para repositorio
86+
class DataBAse(VirtualDataBaseinMemory):
87+
def __init__(self):
88+
self.orders = []
89+
90+
def AddOrder(self, order: VirtualOrder):
91+
self.orders.append(order)
92+
93+
def ListOrder(self):
94+
print(f" Orders in DB")
95+
for o in self.orders:
96+
print(f"{type(o).__name__} : {o.name} ")
97+
98+
99+
# classe para procesar ordenes
100+
101+
class OrderProcess():
102+
def __init__(self, order: VirtualOrder):
103+
self.order = order
104+
105+
def ProcessOrder(self ):
106+
print(f"{ self.order.Process()}")
107+
108+
109+
# class para procesar notificaciones
110+
111+
class NotificationProcess:
112+
def __init__(self, Notification: VirtualNotification):
113+
self.notification = Notification
114+
115+
def ClientNotification(self):
116+
print(f"{ self.notification.SendNotification()}")
117+
118+
# classe que administra repositorio con repositorio
119+
120+
class RepositoryProcess:
121+
def __init__(self, data: VirtualDataBaseinMemory):
122+
self.storage = data
123+
124+
def SaveOrder(self, order: VirtualOrder):
125+
self.storage.AddOrder(order)
126+
127+
def PrintOrders(self ):
128+
self.storage.ListOrder()
129+
130+
131+
132+
class OnlineOrder:
133+
def __init__(self, Process: OrderProcess, Notification: NotificationProcess, Repository: RepositoryProcess):
134+
self.process = Process
135+
self.notification = Notification
136+
self.repository = Repository
137+
138+
def ExecuteProcess(self):
139+
self.process.ProcessOrder()
140+
141+
def ExecuteNotification(self):
142+
self.notification.ClientNotification()
143+
144+
def ExecuteSaveRepository(self, order: VirtualOrder):
145+
self.repository.SaveOrder(order)
146+
147+
def ExecuteListRepository(self):
148+
self.repository.PrintOrders()
149+
150+
151+
# ordenes
152+
e = Electronic("TV")
153+
c = Clothes("Shoes")
154+
b = Books("Odisea")
155+
i = Internet("WIFI Net")
156+
157+
# notificaciones
158+
email = Email()
159+
sms = Sms()
160+
whatsapp = Whatsapp()
161+
telegram = Telegram()
162+
163+
# repositorio
164+
DB = DataBAse()
165+
166+
# crear orden con nueva notificacion
167+
P = OrderProcess(e) # creando procesando la orden e
168+
N = NotificationProcess(email) # creando notificando por email
169+
R = RepositoryProcess(DB) # procesando repositorio la orden e
170+
171+
172+
OL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio
173+
OL.ExecuteProcess() # executando proceso
174+
OL.ExecuteNotification() # executando notificacion
175+
OL.ExecuteSaveRepository(P.order) # executando salva en el repo
176+
177+
# crear orden con nueva notificacion
178+
P = OrderProcess(b) # creando procesando la orden e
179+
N = NotificationProcess(sms) # creando notificando por email
180+
181+
182+
OL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio
183+
OL.ExecuteProcess() # executando proceso
184+
OL.ExecuteNotification() # executando notificacion
185+
OL.ExecuteSaveRepository(P.order) # executando salva en el repo
186+
187+
# crear orden con nueva notificacion
188+
P = OrderProcess(c) # creando procesando la orden e
189+
N = NotificationProcess(whatsapp) # creando notificando por email
190+
191+
192+
OL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio
193+
OL.ExecuteProcess() # executando proceso
194+
OL.ExecuteNotification() # executando notificacion
195+
OL.ExecuteSaveRepository(P.order) # executando salva en el repo
196+
197+
# crear orden con nueva notificacion
198+
P = OrderProcess(i) # creando procesando la orden e
199+
N = NotificationProcess(telegram) # creando notificando por email
200+
201+
202+
OL = OnlineOrder(P,N,R) # orquestador necsita proceso, la notificacion y el repositorio
203+
OL.ExecuteProcess() # executando proceso
204+
OL.ExecuteNotification() # executando notificacion
205+
OL.ExecuteSaveRepository(P.order) # executando salva en el repo
206+
207+
208+
OL.ExecuteListRepository() # executando Listado
209+
210+
211+
212+
213+
214+
215+
# ¡Ahora sí que sí! 🙌 Este código está muy bien estructurado y está aplicando principios de diseño muy sólidos. Vamos por partes para darte un análisis claro, directo y útil 👇
216+
# ✅ Puntos fuertes
217+
# 🧱 1. Principios SOLID
218+
# Principio ¿Cumplido? Comentario
219+
# SRP - Responsabilidad única ✅ Cada clase hace una sola cosa (procesar orden, notificar, guardar).
220+
# OCP - Abierto/Cerrado ✅ Puedes agregar nuevos tipos de pedidos o notificaciones sin modificar nada existente.
221+
# LSP - Sustitución de Liskov ✅ Todas las clases hijas pueden reemplazar a las padres sin romper nada.
222+
# ISP - Segregación de interfaces ✅ Interfaces pequeñas y específicas (VirtualOrder, VirtualNotification, etc.).
223+
# DIP - Inversión de dependencias ✅✔️ Tus clases dependen de abstracciones, no de implementaciones concretas. El cliente aún instancia objetos concretos, pero está bien para este nivel de aplicación. Si lo complementas con una factory externa, ya es perfecto.
224+
# 🔁 2. Extensible y mantenible
225+
226+
# Agregaste una nueva clase Internet sin modificar el código existente ✅
227+
228+
# Agregaste Telegram como nuevo tipo de notificación sin tocar clases previas ✅
229+
230+
# Solo cambias en el "cliente", no en la lógica base del sistema ✅
231+
232+
# 💡 3. Claridad y separación de responsabilidades
233+
234+
# Tu OnlineOrder actúa como un orquestador que agrupa el flujo de procesamiento, notificación y almacenamiento. Muy buena idea, fácil de testear y mantener. ✔️
235+
# 🧪 4. Perfecto para unit testing
236+
237+
# Todas las clases están desacopladas y fácilmente testeables por separado. Por ejemplo:
238+
239+
# def test_sms_notification():
240+
# sms = Sms()
241+
# assert sms.SendNotification() == " SMS message sent"
242+
243+
# 🛠️ Recomendaciones menores
244+
245+
# Aquí unas sugerencias que podrían darte un toque más profesional:
246+
# 1. Renombrar DataBAse → DataBase
247+
248+
# Solo un pequeño error tipográfico.
249+
# 2. Fábrica para instanciar pedidos y notificaciones (si quieres llevarlo al siguiente nivel)
250+
251+
# Esto haría que tu código cumpla DIP al 100% y facilitaría leer desde un archivo o formulario web:
252+
253+
# def create_order(order_type: str, name: str) -> VirtualOrder:
254+
# orders = {
255+
# "internet": Internet,
256+
# "electronic": Electronic,
257+
# "clothes": Clothes,
258+
# "books": Books,
259+
# }
260+
# return orders[order_type](name)
261+
262+
# def create_notification(method: str) -> VirtualNotification:
263+
# notifications = {
264+
# "email": Email,
265+
# "sms": Sms,
266+
# "whatsapp": Whatsapp,
267+
# "telegram": Telegram
268+
# }
269+
# return notifications[method]
270+
271+
# 3. Renombrar algunas variables para más claridad
272+
273+
# En vez de:
274+
275+
# P = OrderProcess(e)
276+
# N = NotificationProcess(email)
277+
278+
# Podrías usar:
279+
280+
# order_process = OrderProcess(e)
281+
# notification_process = NotificationProcess(email)
282+
283+
# Esto mejora la legibilidad, especialmente en proyectos grandes.
284+
# 4. Devolver en vez de imprimir
285+
286+
# Para que el sistema sea más reutilizable y testable, mejor que las funciones como ProcessOrder() o ClientNotification() devuelvan en lugar de imprimir:
287+
288+
# def ProcessOrder(self):
289+
# return self.order.Process()
290+
291+
# # y en el cliente:
292+
# print(OL.process.ProcessOrder())
293+
294+
295+
296+
# Refactor Sugerido (Mini-ejemplo)
297+
# python
298+
299+
# Podrías crear un builder/factory para simplificar
300+
# class OrderBuilder:
301+
# def __init__(self, db):
302+
# self.db = db
303+
304+
# def create_order(self, order, notifier):
305+
# processor = OrderProcess(order)
306+
# notifier = NotificationProcess(notifier)
307+
# repo = RepositoryProcess(self.db)
308+
# return OnlineOrder(processor, notifier, repo)
309+
310+
# # Uso:
311+
# builder = OrderBuilder(DB)
312+
# ol = builder.create_order(e, email)
313+
# ol.ExecuteProcess()
314+
# ol.ExecuteNotification()
315+
316+
# 🏁 Conclusión final
317+
318+
# 🎯 Tu diseño está excelente.
319+
320+
# ✅ Aplica SOLID perfectamente.
321+
# ✅ Es fácil de extender.
322+
# ✅ Está muy limpio, sin acoplamiento innecesario.
323+
# ✅ Es perfecto como base para una app real (con GUI, API o CLI).
324+
# ✅ El cliente tiene control completo del flujo sin modificar la lógica de negocio.
325+
326+
# Si lo que querías era aplicar OOP, buenas prácticas y SOLID de verdad, lo has clavado.
327+
# ¿Quieres que te prepare una versión con factories, entrada por input() o con interfaz básica por consola?

0 commit comments

Comments
 (0)