Observer Pattern (Behavioral Pattern):
# Subject
class Subject:
def __init__(self):
self._observers = []
def attach(self, observer):
self._observers.append(observer)
def detach(self, observer):
self._observers.remove(observer)
def notify(self):
for observer in self._observers:
[Link](self)
# Observer
class Observer:
def update(self, subject):
pass
# ConcreteSubject
class ConcreteSubject(Subject):
def __init__(self):
super().__init__()
self._state = None
def set_state(self, state):
self._state = state
[Link]()
def get_state(self):
return self._state
# ConcreteObserver
class ConcreteObserver(Observer):
def update(self, subject):
print(f"Observer notified. New state: {subject.get_state()}")
Usage:
subject = ConcreteSubject()
observer1 = ConcreteObserver()
observer2 = ConcreteObserver()
[Link](observer1)
[Link](observer2)
subject.set_state("New Update!")
Singleton Pattern (Creational Pattern):
class Singleton:
_instance = None
def __new__(cls):
if cls._instance is None:
print("Creating Singleton instance...")
cls._instance = super(Singleton, cls).__new__(cls)
return cls._instance
def get_service(self):
print("Service provided by the Singleton instance.")
Usage:
a = Singleton()
b = Singleton()
print(a is b) # It will return true
Adapter Pattern (Structural Pattern):
# Target Interface
class Pizza:
def toppings(self):
pass
def bun(self):
pass
# Adaptee
class ChittagongPizza:
def sausage(self):
print("Ctg pizza")
def bread(self):
print("Ctg bread")
# Adapter using inheritance (simulate with composition in Python)
class ChittagongClassAdapter(ChittagongPizza, Pizza):
def toppings(self):
[Link]()
def bun(self):
[Link]()
Object Adapter (uses composition):
# Object Adapter
class ChittagongObjectAdapter(Pizza):
def __init__(self):
self.ctg_pizza = ChittagongPizza()
def toppings(self):
self.ctg_pizza.sausage()
def bun(self):
self.ctg_pizza.bread()
Usage:
pizza = ChittagongObjectAdapter()
[Link]()
[Link]()