Skip to content

Commit b6f7890

Browse files
committed
🔧 Adding
Observer Pattern
1 parent 438dbb2 commit b6f7890

File tree

2 files changed

+98
-13
lines changed

2 files changed

+98
-13
lines changed
Lines changed: 77 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,77 @@
1+
from abc import ABC, abstractmethod
2+
from typing import List
3+
4+
5+
# Observer Interface
6+
class Subscriber(ABC):
7+
@abstractmethod
8+
def update(self, product_name: str):
9+
...
10+
11+
12+
# Concreate Observers
13+
class EmailCustomer(Subscriber):
14+
def __init__(self, name: str, email: str):
15+
self.name = name
16+
self.email = email
17+
18+
def update(self, product_name: str):
19+
print(f"[Email] To: {self.email} | {self.name}, the product '{product_name}' is now available.")
20+
21+
22+
class SMSCustomer(Subscriber):
23+
def __init__(self, name: str, phone: str):
24+
self.name = name
25+
self.phone = phone
26+
27+
def update(self, product_name: str):
28+
print(f"[SMS] To: {self.phone} | {self.name}, the product '{product_name}' is available.")
29+
30+
31+
# PUBLISHER Class
32+
33+
class Store:
34+
def __init__(self, store_name: str):
35+
self.store_name = store_name
36+
self._subscribers: List[Subscriber] = []
37+
38+
def subscribe(self, subscriber: Subscriber):
39+
self._subscribers.append(subscriber)
40+
print(f"{subscriber.__class__.__name__} subscribed to {self.store_name}")
41+
42+
def unscribe(self, subscriber: Subscriber):
43+
self._subscribers.remove(subscriber)
44+
print(f"{subscriber.__class__.__name__} unsubscribed from {self.store_name}")
45+
46+
def notify_subscriber(self, product_name: str):
47+
print(f"\n[{self.store_name}] Notifying all subscriber about: {product_name}")
48+
for subscriber in self._subscribers:
49+
subscriber.update(product_name)
50+
51+
def add_new_product(self, product_name: str):
52+
print(f"\n[{self.store_name}] New Product added: {product_name}")
53+
self.notify_subscriber(product_name)
54+
55+
56+
# Client Code
57+
58+
if __name__ == "__main__":
59+
# Create a store (Publisher)
60+
apple_store = Store("Apple Store")
61+
62+
# Create customers (Subscribers)
63+
john = EmailCustomer("John Doe", "[email protected]")
64+
jane = SMSCustomer("Jane Doe", "+1288488483")
65+
66+
# Subscriptions
67+
apple_store.subscribe(john)
68+
apple_store.subscribe(jane)
69+
70+
# Store adds a product
71+
apple_store.add_new_product("Iphone 20 Max Pro")
72+
73+
# Unsubscribe Jane
74+
apple_store.unscribe(jane)
75+
76+
# Add another product
77+
apple_store.add_new_product("Mac Book Air 20 Plus")

Data/Pro Vs Cons.html

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
<head>
44
<meta charset="UTF-8">
55
<meta name="viewport" content="width=device-width, initial-scale=1.0">
6-
<title>Prototype Design Pattern: Pros vs. Cons</title>
6+
<title>Visitor Design Pattern: Pros vs. Cons</title>
77
<!-- Google Fonts: Inter -->
88
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@400;600;700&display=swap" rel="stylesheet">
99
<!-- Tailwind CSS CDN -->
@@ -35,11 +35,11 @@
3535

3636
<div class="container mx-auto bg-white shadow-2xl overflow-hidden max-w-6xl w-full">
3737
<!-- Header Section -->
38-
<div class="bg-gradient-to-r from-teal-600 to-cyan-700 text-white p-6 md:p-8 text-center">
38+
<div class="bg-gradient-to-r from-green-700 to-lime-600 text-white p-6 md:p-8 text-center">
3939
<h1 class="text-3xl md:text-5xl font-extrabold mb-2 leading-tight">
40-
<span class="block text-amber-300 mb-2"><i class="fa-solid fa-robot"></i></span> Prototype Design Pattern: Pros vs. Cons
40+
<span class="block text-amber-300 mb-2"><i class="fa-solid fa-person-walking"></i></span> Visitor Design Pattern: Pros vs. Cons
4141
</h1>
42-
<p class="text-lg md:text-xl font-light opacity-90">Creating Families of Related Objects</p>
42+
<p class="text-lg md:text-xl font-light opacity-90">Adding New Operations to Existing Object Structures Without Modifying Them</p>
4343
</div>
4444

4545
<!-- Main Content: Pros and Cons Columns -->
@@ -57,39 +57,39 @@ <h2 class="text-2xl md:text-3xl font-bold text-green-700 mb-6 flex items-center"
5757
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
5858
</span>
5959
<div class="flex-1">
60-
<span class="font-bold">Reduces the need for subclassing:</span> You can create new objects by copying existing ones, avoiding the need for many subclasses.
60+
<span class="font-bold">Open/Closed Principle:</span> New operations can be added without modifying the existing object structure.
6161
</div>
6262
</li>
6363
<li class="flex items-start">
6464
<span class="flex-shrink-0 text-green-500 mt-1 mr-3">
6565
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
6666
</span>
6767
<div class="flex-1">
68-
<span class="font-bold">Hides the complexity of object creation:</span> Clients can clone objects without knowing the details of their construction.
68+
<span class="font-bold">Separation of concerns:</span> Operations are separated from the objects on which they operate, improving maintainability.
6969
</div>
7070
</li>
7171
<li class="flex items-start">
7272
<span class="flex-shrink-0 text-green-500 mt-1 mr-3">
7373
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
7474
</span>
7575
<div class="flex-1">
76-
<span class="font-bold">Speeds up the instantiation of complex objects:</span> Cloning is often faster than constructing a new object from scratch, especially for resource-intensive objects.
76+
<span class="font-bold">Easier to add new behaviors:</span> New visitor classes can be created to add new behaviors without changing existing code.
7777
</div>
7878
</li>
7979
<li class="flex items-start">
8080
<span class="flex-shrink-0 text-green-500 mt-1 mr-3">
8181
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
8282
</span>
8383
<div class="flex-1">
84-
<span class="font-bold">Allows adding and removing objects at runtime:</span> New prototypes can be registered and cloned as needed, providing flexibility.
84+
<span class="font-bold">Supports operations across class hierarchies:</span> Can perform operations on a set of objects with different concrete classes.
8585
</div>
8686
</li>
8787
<li class="flex items-start">
8888
<span class="flex-shrink-0 text-green-500 mt-1 mr-3">
8989
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z" clip-rule="evenodd"></path></svg>
9090
</span>
9191
<div class="flex-1">
92-
<span class="font-bold">Useful for objects that are expensive to create:</span> Especially when object creation involves a costly setup or configuration process.
92+
<span class="font-bold">Facilitates adding features:</span> Useful for adding features like traversals, reporting, or exporting without modifying the object structure.
9393
</div>
9494
</li>
9595
</ul>
@@ -107,31 +107,39 @@ <h2 class="text-2xl md:text-3xl font-bold text-red-700 mb-6 flex items-center">
107107
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg>
108108
</span>
109109
<div class="flex-1">
110-
<span class="font-bold">Cloning complex objects with circular references can be tricky:</span> Special care is needed to avoid infinite loops or errors during cloning.
110+
<span class="font-bold">Breaks encapsulation:</span> The visitor may need to access internal details of elements, breaking encapsulation.
111111
</div>
112112
</li>
113113
<li class="flex items-start">
114114
<span class="flex-shrink-0 text-red-500 mt-1 mr-3">
115115
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg>
116116
</span>
117117
<div class="flex-1">
118-
<span class="font-bold">Requires implementing a cloning method for each prototype:</span> Every class that needs to be cloned must provide its own cloning logic.
118+
<span class="font-bold">Difficult to add new element types:</span> Adding new element classes requires updating all existing visitors.
119119
</div>
120120
</li>
121121
<li class="flex items-start">
122122
<span class="flex-shrink-0 text-red-500 mt-1 mr-3">
123123
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg>
124124
</span>
125125
<div class="flex-1">
126-
<span class="font-bold">Deep copy vs. shallow copy issues can arise:</span> Care must be taken to ensure the correct type of copy is made, especially for objects with references to other objects.
126+
<span class="font-bold">Complex double-dispatch:</span> Requires double-dispatch, which can make the code harder to follow and maintain.
127127
</div>
128128
</li>
129129
<li class="flex items-start">
130130
<span class="flex-shrink-0 text-red-500 mt-1 mr-3">
131131
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg>
132132
</span>
133133
<div class="flex-1">
134-
<span class="font-bold">Not always clear when to use:</span> Sometimes using constructors or factory methods is simpler and more appropriate than cloning.
134+
<span class="font-bold">Can be overkill for simple structures:</span> Adds unnecessary complexity if only a few operations are needed.
135+
</div>
136+
</li>
137+
<li class="flex items-start">
138+
<span class="flex-shrink-0 text-red-500 mt-1 mr-3">
139+
<svg class="w-6 h-6" fill="currentColor" viewBox="0 0 20 20" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" d="M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z" clip-rule="evenodd"></path></svg>
140+
</span>
141+
<div class="flex-1">
142+
<span class="font-bold">Visitor pattern can break encapsulation:</span> The visitor may require access to the internal state of elements, which can break encapsulation.
135143
</div>
136144
</li>
137145
</ul>

0 commit comments

Comments
 (0)